Commit a0227cab authored by Hixie's avatar Hixie

flutter analyze command

Other changes in this patch:
- Make the 'flutter' tool say "Updating flutter tool..." when it calls
  pub get, to avoid confusion about what the pub get output is about.
- Make the bash flutter tool call pub get when the revision has
  changed. (This was already happening on Windows.)
- Fix a raft of bugs found by the analyzer.
- Fix some style nits in various bits of code that happened to be near
  things the analyzer noticed.
- Remove the logic in "flutter test" that would run "pub get", since
  upon further reflexion it was determined it didn't work anyway.
  We'll probably have to add better diagnostics here and say to run the
  updater script.
- Remove the native velocity tracker script, since it was testing code
  that has since been removed.

Notes on ignored warnings:
- We ignore warnings in any packages that are not in the Flutter repo or
  in the author's current directory.
- We ignore various irrelevant Strong Mode warnings. We still enable
  strong mode because even though it's not really relevant to our needs,
  it does (more or less accidentally) catch a few things that are
  helpful to us.
- We allow CONSTANTS_LIKE_THIS, since we get some of those from other
  platforms that we are copying for sanity and consistency.
- We allow one-member abstract classes since we have a number of them
  where it's perfectly reasonable.
- We unfortunately still ignore warnings in mojom.dart autogenerated
  files. We should really fix those but that's a separate patch.
- We verify the actual source file when we see the 'Name non-constant
  identifiers using lowerCamelCase.' lint, to allow one-letter variables
  that use capital letters (e.g. for physics expressions) and to allow
  multiple-underscore variable names.
- We ignore all errors on lines that contain the following magic
  incantation and a "#" character:
    // analyzer doesn't like constructor tear-offs
- For all remaining errors, if the line contains a comment of the form
    // analyzer says "..."
  ...then we ignore any errors that have that "..." string in them.
parent 0758fea1
......@@ -12,16 +12,10 @@ SCRIPT_PATH="$FLUTTER_TOOLS_DIR/bin/flutter_tools.dart"
# TODO(abarth): We shouldn't require dart to be on the user's path.
DART=dart
if [ "$FLUTTER_TOOLS_DIR/pubspec.yaml" -nt "$FLUTTER_TOOLS_DIR/pubspec.lock" ]; then
(cd "$FLUTTER_TOOLS_DIR"; pub get)
if [ -f "$SNAPSHOT_PATH" ]; then
rm "$SNAPSHOT_PATH"
fi
fi
REVISION=`(cd "$FLUTTER_ROOT"; git rev-parse HEAD)`
if [ ! -f "$SNAPSHOT_PATH" ] || [ ! -f "$STAMP_PATH" ] || [ `cat "$STAMP_PATH"` != $REVISION ]; then
if [ ! -f "$SNAPSHOT_PATH" ] || [ ! -f "$STAMP_PATH" ] || [ `cat "$STAMP_PATH"` != $REVISION ] || [ "$FLUTTER_TOOLS_DIR/pubspec.yaml" -nt "$FLUTTER_TOOLS_DIR/pubspec.lock" ]; then
echo Updating flutter tool...
(cd "$FLUTTER_TOOLS_DIR"; pub get)
$DART --snapshot="$SNAPSHOT_PATH" --package-root="$FLUTTER_TOOLS_DIR/packages" "$SCRIPT_PATH"
echo -n $REVISION > "$STAMP_PATH"
fi
......
......@@ -29,6 +29,7 @@ GOTO :after_snapshot
:do_snapshot
CD "%flutter_tools_dir%"
ECHO Updating flutter tool...
CALL pub.bat get
CD "%flutter_root%"
CALL %dart% --snapshot="%snapshot_path%" --package-root="%flutter_tools_dir%\packages" "%script_path%"
......@@ -42,4 +43,4 @@ CALL %dart% "%snapshot_path%" %*
IF /I "%ERRORLEVEL%" EQU "253" (
CALL %dart% --snapshot="%snapshot_path%" --package-root="%flutter_tools_dir%\packages" "%script_path%"
CALL %dart% "%snapshot_path%" %*
)
\ No newline at end of file
)
......@@ -124,7 +124,7 @@ class FitnessAppState extends State<FitnessApp> {
});
}
Widget build(BuildContext) {
Widget build(BuildContext context) {
return new MaterialApp(
theme: new ThemeData(
brightness: ThemeBrightness.light,
......
......@@ -38,7 +38,7 @@ final ThemeData _theme = new ThemeData(
);
class TestAppState extends State<TestApp> {
TestApp() {
TestAppState() {
_testBed = new TestBed(_labelTexts[_selectedLine]);
}
......
......@@ -44,10 +44,10 @@ class TabbedNavigatorAppState extends State<TabbedNavigatorApp> {
TabNavigator _buildIconLabelsTabNavigator(int n) {
Iterable<TabNavigatorView> views = ["event", "home", "android", "alarm", "face", "language"]
.map((icon_name) {
.map((String iconName) {
return new TabNavigatorView(
label: new TabLabel(icon: "action/$icon_name"),
builder: (BuildContext context) => _buildContent(icon_name)
label: new TabLabel(icon: "action/$iconName"),
builder: (BuildContext context) => _buildContent(iconName)
);
});
return _buildTabNavigator(n, views.toList(), const ValueKey<String>('iconLabelsTabNavigator'));
......
......@@ -21,20 +21,20 @@ class Constraint {
switch (relation) {
case Relation.equalTo:
buffer.write(" == 0 ");
buffer.write(' == 0 ');
break;
case Relation.greaterThanOrEqualTo:
buffer.write(" >= 0 ");
buffer.write(' >= 0 ');
break;
case Relation.lessThanOrEqualTo:
buffer.write(" <= 0 ");
buffer.write(' <= 0 ');
break;
}
buffer.write(" | priority = ${priority}");
buffer.write(' | priority = $priority');
if (priority == Priority.required) {
buffer.write(" (required)");
buffer.write(' (required)');
}
return buffer.toString();
......
......@@ -58,7 +58,7 @@ class Expression extends _EquationMember {
_createConstraint(value, Relation.lessThanOrEqualTo);
operator ==(_EquationMember value) =>
_createConstraint(value, Relation.equalTo);
_createConstraint(value, Relation.equalTo); // analyzer says "Type check failed" // analyzer says "The return type 'Constraint' is not a 'bool', as defined by the method '=='"
Expression operator +(_EquationMember m) {
if (m is ConstantMember) {
......@@ -140,7 +140,7 @@ class Expression extends _EquationMember {
if (args == null) {
throw new ParserException(
"Could not find constant multiplicand or multiplier", [this, m]);
'Could not find constant multiplicand or multiplier', [this, m]);
return null;
}
......@@ -150,7 +150,7 @@ class Expression extends _EquationMember {
_EquationMember operator /(_EquationMember m) {
if (!m.isConstant) {
throw new ParserException(
"The divisor was not a constant expression", [this, m]);
'The divisor was not a constant expression', [this, m]);
return null;
}
......@@ -160,10 +160,10 @@ class Expression extends _EquationMember {
String toString() {
StringBuffer buffer = new StringBuffer();
terms.forEach((t) => buffer.write("${t}"));
terms.forEach((t) => buffer.write('$t'));
if (constant != 0.0) {
buffer.write(constant.sign > 0.0 ? "+" : "-");
buffer.write(constant.sign > 0.0 ? '+' : '-');
buffer.write(constant.abs());
}
......
......@@ -410,10 +410,10 @@ class Solver {
double temp = row.coefficientForSymbol(entering);
if (temp < 0.0) {
double temp_ratio = -row.constant / temp;
double tempRatio = -row.constant / temp;
if (temp_ratio < ratio) {
ratio = temp_ratio;
if (tempRatio < ratio) {
ratio = tempRatio;
result.first = symbol;
result.second = row;
}
......
......@@ -13,24 +13,24 @@ class _Symbol {
_Symbol(this.type, this.tick);
String toString() {
String typeString = "unknown";
String typeString = 'unknown';
switch (type) {
case _SymbolType.invalid:
typeString = "i";
typeString = 'i';
break;
case _SymbolType.external:
typeString = "v";
typeString = 'v';
break;
case _SymbolType.slack:
typeString = "s";
typeString = 's';
break;
case _SymbolType.error:
typeString = "e";
typeString = 'e';
break;
case _SymbolType.dummy:
typeString = "d";
typeString = 'd';
break;
}
return "${typeString}${tick}";
return '$typeString$tick';
}
}
......@@ -21,7 +21,7 @@ class Variable {
return res;
}
String get debugName => _elvis(name, "variable${_tick}");
String get debugName => _elvis(name, 'variable$_tick');
String toString() => debugName;
}
......@@ -114,7 +114,7 @@ Future<String> read(url) =>
Future<Uint8List> readBytes(url) =>
_withClient((client) => client.readBytes(url));
Future _withClient(Future fn(MojoClient)) {
Future _withClient(Future fn(MojoClient client)) {
var client = new MojoClient();
var future = fn(client);
return future.whenComplete(client.close);
......
......@@ -132,7 +132,11 @@ class _PointerEventConverter {
return 'mouse';
case PointerKind.STYLUS:
return 'stylus';
case PointerKind.INVERTED_STYLUS:
return 'invertedStylus';
}
assert(false);
return '';
}
}
......
......@@ -3,7 +3,7 @@ part of flutter_sprites;
// TODO: The sound effects should probably use Android's SoundPool instead of
// MediaPlayer as it is more efficient and flexible for playing back sound effects
typedef void SoundEffectStreamCallback(SoundEffectStream);
typedef void SoundEffectStreamCallback(SoundEffectStream stream);
class SoundEffect {
SoundEffect(this._pipeFuture);
......@@ -137,8 +137,8 @@ class SoundEffectPlayer {
}
}
typedef void SoundTrackCallback(SoundTrack);
typedef void SoundTrackBufferingCallback(SoundTrack, int);
typedef void SoundTrackCallback(SoundTrack soundTrack);
typedef void SoundTrackBufferingCallback(SoundTrack soundTrack, int index);
class SoundTrack {
MediaPlayerProxy _player;
......
......@@ -9,6 +9,7 @@ import 'package:args/command_runner.dart';
import 'package:logging/logging.dart';
import 'package:stack_trace/stack_trace.dart';
import 'src/commands/analyze.dart';
import 'src/commands/build.dart';
import 'src/commands/cache.dart';
import 'src/commands/daemon.dart';
......@@ -46,6 +47,7 @@ Future main(List<String> args) async {
});
FlutterCommandRunner runner = new FlutterCommandRunner()
..addCommand(new AnalyzeCommand())
..addCommand(new BuildCommand())
..addCommand(new CacheCommand())
..addCommand(new DaemonCommand())
......
......@@ -48,9 +48,9 @@ String _getCloudStorageBaseUrl({String category, String platform, String revisio
// In the fullness of time, we'll have a consistent URL pattern for all of
// our artifacts, but, for the time being, Mac OS X artifacts are stored in a
// different cloud storage bucket.
return 'https://storage.googleapis.com/mojo_infra/flutter/${platform}/${revision}/';
return 'https://storage.googleapis.com/mojo_infra/flutter/$platform/$revision/';
}
return 'https://storage.googleapis.com/mojo/sky/${category}/${platform}/${revision}/';
return 'https://storage.googleapis.com/mojo/sky/$category/$platform/$revision/';
}
enum ArtifactType {
......
This diff is collapsed.
......@@ -93,7 +93,7 @@ dynamic _loadManifest(String manifestPath) {
}
ArchiveFile _createFile(String key, String assetBase) {
File file = new File('${assetBase}/${key}');
File file = new File('$assetBase/$key');
if (!file.existsSync())
return null;
List<int> content = file.readAsBytesSync();
......
......@@ -60,7 +60,7 @@ class DaemonCommand extends FlutterCommand {
stdout.writeln('[${JSON.encode(command)}]');
}, daemonCommand: this);
return daemon.onExit;
return await daemon.onExit;
}
}
......@@ -98,19 +98,19 @@ class Daemon {
var id = command['id'];
if (id == null) {
_logging.severe('no id for command: ${command}');
_logging.severe('no id for command: $command');
return;
}
try {
String event = command['event'];
if (event.indexOf('.') == -1)
throw 'command not understood: ${event}';
throw 'command not understood: $event';
String prefix = event.substring(0, event.indexOf('.'));
String name = event.substring(event.indexOf('.') + 1);
if (_domains[prefix] == null)
throw 'no domain for command: ${command}';
throw 'no domain for command: $command';
_domains[prefix].handleEvent(name, id, command['params']);
} catch (error, trace) {
......@@ -144,7 +144,7 @@ abstract class Domain {
new Future.sync(() {
if (_handlers.containsKey(name))
return _handlers[name](args);
throw 'command not understood: ${name}';
throw 'command not understood: $name';
}).then((result) {
if (result == null) {
_send({'id': id});
......@@ -153,7 +153,7 @@ abstract class Domain {
}
}).catchError((error, trace) {
_send({'id': id, 'error': _toJsonable(error)});
_logging.warning('error handling ${name}', error, trace);
_logging.warning('error handling $name', error, trace);
});
}
......@@ -210,5 +210,5 @@ class AppDomain extends Domain {
dynamic _toJsonable(dynamic obj) {
if (obj is String || obj is int || obj is bool || obj is Map || obj is List || obj == null)
return obj;
return '${obj}';
return '$obj';
}
......@@ -56,7 +56,7 @@ abstract class FlutterCommand extends Command {
}
}
return runInProject();
return await runInProject();
}
Future<int> runInProject();
......
......@@ -6,12 +6,15 @@ import 'dart:async';
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:logging/logging.dart';
import 'package:mustache4dart/mustache4dart.dart' as mustache;
import 'package:path/path.dart' as p;
import '../artifacts.dart';
import '../process.dart';
final Logger _logging = new Logger('sky_tools.init');
class InitCommand extends Command {
final String name = 'init';
final String description = 'Create a new Flutter project.';
......@@ -20,7 +23,7 @@ class InitCommand extends Command {
argParser.addOption('out', abbr: 'o', help: 'The output directory.');
argParser.addFlag('pub',
defaultsTo: true,
help: 'Whether to run pub after the project has been created.');
help: 'Whether to run "pub get" after the project has been created.');
}
@override
......@@ -40,7 +43,7 @@ class InitCommand extends Command {
String flutterPackagePath = p.join(flutterRoot, 'packages', 'flutter');
if (!FileSystemEntity.isFileSync(p.join(flutterPackagePath, 'pubspec.yaml'))) {
print('Unable to find package:flutter in ${flutterPackagePath}');
print('Unable to find package:flutter in $flutterPackagePath');
return 2;
}
......@@ -58,17 +61,48 @@ class InitCommand extends Command {
''';
if (argResults['pub']) {
print("Running pub get...");
int code = await pubGet(directory: out.path);
if (code != 0)
return code;
}
print(message);
return 0;
}
Future<int> pubGet({
String directory: '',
bool skipIfAbsent: false,
bool verbose: true
}) async {
File pubSpecYaml = new File(p.join(directory, 'pubspec.yaml'));
File pubSpecLock = new File(p.join(directory, 'pubspec.lock'));
File dotPackages = new File(p.join(directory, '.packages'));
if (!pubSpecYaml.existsSync()) {
if (skipIfAbsent)
return 0;
_logging.severe('$directory: no pubspec.yaml found');
return 1;
}
if (!pubSpecLock.existsSync() || pubSpecYaml.lastModifiedSync().isAfter(pubSpecLock.lastModifiedSync())) {
if (verbose)
print("Running pub get in $directory...");
int code = await runCommandAndStreamOutput(
[sdkBinaryName('pub'), 'get'],
workingDirectory: out.path
workingDirectory: directory
);
if (code != 0)
return code;
}
print(message);
return 0;
if ((pubSpecLock.existsSync() && pubSpecLock.lastModifiedSync().isAfter(pubSpecYaml.lastModifiedSync())) &&
(dotPackages.existsSync() && dotPackages.lastModifiedSync().isAfter(pubSpecYaml.lastModifiedSync())))
return 0;
_logging.severe('$directory: pubspec.yaml, pubspec.lock, and .packages are in an inconsistent state');
return 1;
}
}
......
......@@ -34,7 +34,7 @@ class RunMojoCommand extends Command {
String _makePathAbsolute(String relativePath) {
File file = new File(relativePath);
if (!file.existsSync()) {
throw new Exception("Path \"${relativePath}\" does not exist");
throw new Exception('Path "$relativePath" does not exist');
}
return file.absolute.path;
}
......@@ -79,8 +79,8 @@ class RunMojoCommand extends Command {
final appPath = _makePathAbsolute(argResults['app']);
Artifact artifact = ArtifactStore.getArtifact(type: ArtifactType.viewer, targetPlatform: TargetPlatform.linux);
final viewerPath = _makePathAbsolute(await ArtifactStore.getPath(artifact));
args.add('file://${appPath}');
args.add('--url-mappings=mojo:sky_viewer=file://${viewerPath}');
args.add('file://$appPath');
args.add('--url-mappings=mojo:sky_viewer=file://$viewerPath');
}
if (useDevtools) {
......@@ -115,6 +115,6 @@ class RunMojoCommand extends Command {
return 1;
}
return runCommandAndStreamOutput(await _getShellConfig());
return await runCommandAndStreamOutput(await _getShellConfig());
}
}
......@@ -68,7 +68,7 @@ class StartCommand extends FlutterCommand {
if (FileSystemEntity.isDirectorySync(target))
mainPath = path.join(target, 'lib', 'main.dart');
if (!FileSystemEntity.isFileSync(mainPath)) {
String message = 'Tried to run ${mainPath}, but that file does not exist.';
String message = 'Tried to run $mainPath, but that file does not exist.';
if (!argResults.wasParsed('target'))
message += '\nConsider using the -t option to specify that Dart file to start.';
stderr.writeln(message);
......
......@@ -11,7 +11,6 @@ import 'package:test/src/executable.dart' as executable;
import '../artifacts.dart';
import '../build_configuration.dart';
import '../process.dart';
import '../test/loader.dart' as loader;
import 'flutter_command.dart';
......@@ -49,25 +48,6 @@ class TestCommand extends FlutterCommand {
testArgs.insert(0, '--no-color');
List<BuildConfiguration> configs = buildConfigurations;
bool foundOne = false;
File pubSpecYaml = new File(path.join(flutterDir.path, 'pubspec.yaml'));
File pubSpecLock = new File(path.join(flutterDir.path, 'pubspec.lock'));
if (!pubSpecYaml.existsSync()) {
print('${flutterDir.path} has no pubspec.yaml');
return 1;
}
if (!pubSpecLock.existsSync() || pubSpecYaml.lastModifiedSync().isAfter(pubSpecLock.lastModifiedSync())) {
print("Running pub get...");
int code = await runCommandAndStreamOutput(
[sdkBinaryName('pub'), 'get'],
workingDirectory: flutterDir.path
);
if (code != 0)
return code;
}
String currentDirectory = Directory.current.path;
Directory.current = flutterDir.path;
loader.installHook();
......
......@@ -19,36 +19,8 @@ abstract class Device {
final String id;
static Map<String, Device> _deviceCache = {};
factory Device._unique(String className, [String id = null]) {
if (id == null) {
if (className == AndroidDevice.className) {
id = AndroidDevice.defaultDeviceID;
} else if (className == IOSDevice.className) {
id = IOSDevice.defaultDeviceID;
} else if (className == IOSSimulator.className) {
id = IOSSimulator.defaultDeviceID;
} else {
throw 'Attempted to create a Device of unknown type $className';
}
}
return _deviceCache.putIfAbsent(id, () {
if (className == AndroidDevice.className) {
final device = new AndroidDevice._(id);
_deviceCache[id] = device;
return device;
} else if (className == IOSDevice.className) {
final device = new IOSDevice._(id);
_deviceCache[id] = device;
return device;
} else if (className == IOSSimulator.className) {
final device = new IOSSimulator._(id);
_deviceCache[id] = device;
return device;
} else {
throw 'Attempted to create a Device of unknown type $className';
}
});
static Device _unique(String id, Device constructor(String id)) {
return _deviceCache.putIfAbsent(id, () => constructor(id));
}
Device._(this.id);
......@@ -74,7 +46,6 @@ abstract class Device {
}
class IOSDevice extends Device {
static const String className = 'IOSDevice';
static final String defaultDeviceID = 'default_ios_id';
static const String _macInstructions =
......@@ -108,7 +79,7 @@ class IOSDevice extends Device {
String get name => _name;
factory IOSDevice({String id, String name}) {
IOSDevice device = new Device._unique(className, id);
IOSDevice device = Device._unique(id ?? defaultDeviceID, new IOSDevice#_); // analyzer doesn't like constructor tear-offs
device._name = name;
return device;
}
......@@ -224,14 +195,17 @@ class IOSDevice extends Device {
}
// idevicedebug hangs forever after launching the app, so kill it after
// giving it plenty of time to send the launch command.
return runAndKill(
[debuggerPath, 'run', app.id], new Duration(seconds: 3)).then(
(_) {
return true;
}, onError: (e) {
_logging.info('Failure running $debuggerPath: ', e);
return false;
});
return await runAndKill(
[debuggerPath, 'run', app.id],
new Duration(seconds: 3)
).then(
(_) {
return true;
}, onError: (e) {
_logging.info('Failure running $debuggerPath: ', e);
return false;
}
);
}
@override
......@@ -274,13 +248,12 @@ class IOSDevice extends Device {
if (!isConnected()) {
return 2;
}
return runCommandAndStreamOutput([loggerPath],
return await runCommandAndStreamOutput([loggerPath],
prefix: 'iOS dev: ', filter: new RegExp(r'.*SkyShell.*'));
}
}
class IOSSimulator extends Device {
static const String className = 'IOSSimulator';
static final String defaultDeviceID = 'default_ios_sim_id';
static const String _macInstructions =
......@@ -299,7 +272,7 @@ class IOSSimulator extends Device {
String get name => _name;
factory IOSSimulator({String id, String name, String iOSSimulatorPath}) {
IOSSimulator device = new Device._unique(className, id);
IOSSimulator device = Device._unique(id ?? defaultDeviceID, new IOSSimulator#_); // analyzer doesn't like constructor tear-offs
device._name = name;
if (iOSSimulatorPath == null) {
iOSSimulatorPath = path.join('/Applications', 'iOS Simulator.app',
......@@ -309,7 +282,7 @@ class IOSSimulator extends Device {
return device;
}
IOSSimulator._(String id) : super._(id) {}
IOSSimulator._(String id) : super._(id);
static String _getRunningSimulatorID([IOSSimulator mockIOS]) {
String xcrunPath = mockIOS != null ? mockIOS.xcrunPath : _xcrunPath;
......@@ -380,7 +353,6 @@ class IOSSimulator extends Device {
}
if (id == defaultDeviceID) {
runDetached([iOSSimPath]);
Future<bool> checkConnection([int attempts = 20]) async {
if (attempts == 0) {
_logging.info('Timed out waiting for iOS Simulator $id to boot.');
......@@ -388,12 +360,12 @@ class IOSSimulator extends Device {
}
if (!isConnected()) {
_logging.info('Waiting for iOS Simulator $id to boot...');
return new Future.delayed(new Duration(milliseconds: 500),
return await new Future.delayed(new Duration(milliseconds: 500),
() => checkConnection(attempts - 1));
}
return true;
}
return checkConnection();
return await checkConnection();
} else {
try {
runCheckedSync([xcrunPath, 'simctl', 'boot', id]);
......@@ -496,7 +468,7 @@ class IOSSimulator extends Device {
if (clear) {
runSync(['rm', logFilePath]);
}
return runCommandAndStreamOutput(['tail', '-f', logFilePath],
return await runCommandAndStreamOutput(['tail', '-f', logFilePath],
prefix: 'iOS sim: ', filter: new RegExp(r'.*SkyShell.*'));
}
}
......@@ -505,7 +477,6 @@ class AndroidDevice extends Device {
static const String _ADB_PATH = 'adb';
static const int _observatoryPort = 8181;
static const String className = 'AndroidDevice';
static final String defaultDeviceID = 'default_android_device';
String productID;
......@@ -522,7 +493,7 @@ class AndroidDevice extends Device {
String productID: null,
String modelID: null,
String deviceCodeName: null}) {
AndroidDevice device = new Device._unique(className, id);
AndroidDevice device = Device._unique(id ?? defaultDeviceID, new AndroidDevice#_); // analyzer doesn't like constructor tear-offs
device.productID = productID;
device.modelID = modelID;
device.deviceCodeName = deviceCodeName;
......@@ -813,7 +784,7 @@ class AndroidDevice extends Device {
clearLogs();
}
return runCommandAndStreamOutput(adbCommandForDevice([
return await runCommandAndStreamOutput(adbCommandForDevice([
'logcat',
'-v',
'tag', // Only log the tag and the message
......
......@@ -18,33 +18,35 @@ Future<int> runCommandAndStreamOutput(List<String> cmd, {
String workingDirectory
}) async {
_logging.info(cmd.join(' '));
Process proc = await Process.start(
Process process = await Process.start(
cmd[0],
cmd.getRange(1, cmd.length).toList(),
cmd.sublist(1),
workingDirectory: workingDirectory
);
proc.stdout.transform(UTF8.decoder).listen((String data) {
process.stdout.transform(UTF8.decoder).listen((String data) {
List<String> dataLines = data.trimRight().split('\n');
if (filter != null) {
// TODO(ianh): This doesn't handle IO buffering (where the data might be split half-way through a line)
dataLines = dataLines.where((String s) => filter.hasMatch(s)).toList();
}
if (dataLines.length > 0) {
stdout.write('$prefix${dataLines.join('\n$prefix')}\n');
}
});
proc.stderr.transform(UTF8.decoder).listen((String data) {
process.stderr.transform(UTF8.decoder).listen((String data) {
List<String> dataLines = data.trimRight().split('\n');
if (filter != null) {
// TODO(ianh): This doesn't handle IO buffering (where the data might be split half-way through a line)
dataLines = dataLines.where((String s) => filter.hasMatch(s));
}
if (dataLines.length > 0) {
stderr.write('$prefix${dataLines.join('\n$prefix')}\n');
}
});
return proc.exitCode;
return await process.exitCode;
}
Future runAndKill(List<String> cmd, Duration timeout) async {
Future runAndKill(List<String> cmd, Duration timeout) {
Future<Process> proc = runDetached(cmd);
return new Future.delayed(timeout, () async {
_logging.info('Intentionally killing ${cmd[0]}');
......@@ -52,7 +54,7 @@ Future runAndKill(List<String> cmd, Duration timeout) async {
});
}
Future<Process> runDetached(List<String> cmd) async {
Future<Process> runDetached(List<String> cmd) {
_logging.info(cmd.join(' '));
Future<Process> proc = Process.start(
cmd[0], cmd.getRange(1, cmd.length).toList(),
......@@ -97,6 +99,6 @@ String _runWithLoggingSync(List<String> cmd, {bool checked: false}) {
class ProcessExit implements Exception {
final int exitCode;
ProcessExit(this.exitCode);
String get message => 'ProcessExit: ${exitCode}';
String get message => 'ProcessExit: $exitCode';
String toString() => message;
}
......@@ -50,8 +50,9 @@ class BoundedFrictionSimulation extends FrictionSimulation {
double drag,
double position,
double velocity,
double this._minX,
double this._maxX) : super(drag, position, velocity);
this._minX,
this._maxX
) : super(drag, position, velocity);
final double _minX;
final double _maxX;
......
......@@ -17,7 +17,8 @@ class SpringDescription {
final double damping;
SpringDescription(
{double this.mass, double this.springConstant, double this.damping}) {
{ this.mass, this.springConstant, this.damping }
) {
assert(mass != null);
assert(springConstant != null);
assert(damping != null);
......
import 'dart:ui' as ui;
import 'package:flutter/gestures.dart';
import 'package:test/test.dart';
import 'velocity_tracker_data.dart';
......@@ -45,20 +43,4 @@ void main() {
watch.stop();
print("Dart tracker: " + watch.elapsed.toString());
});
test('Native velocity tracker performance', () {
ui.VelocityTracker tracker = new ui.VelocityTracker();
Stopwatch watch = new Stopwatch();
watch.start();
for (int i = 0; i < kNumIters; i++) {
for (PointerInputEvent event in events) {
if (event.type == 'pointerdown' || event.type == 'pointermove')
tracker.addPosition((event.timeStamp*1000.0).toInt(), event.x, event.y);
if (event.type == 'pointerup')
tracker.getVelocity();
}
}
watch.stop();
print("Native tracker: " + watch.elapsed.toString());
});
}
......@@ -8,16 +8,19 @@ import 'rendering_tester.dart';
class SquareImage implements ui.Image {
int get width => 10;
int get height => 10;
void dispose() { }
}
class WideImage implements ui.Image {
int get width => 20;
int get height => 10;
void dispose() { }
}
class TallImage implements ui.Image {
int get width => 10;
int get height => 20;
void dispose() { }
}
void main() {
......
#!/bin/bash
set -ex
(cd packages/cassowary; pub global run tuneup check; pub run test -j1)
(cd packages/flutter_sprites; pub global run tuneup check) # No tests to run.
(cd packages/flutter_tools; pub global run tuneup check; pub run test -j1)
(cd packages/flx; pub global run tuneup check; pub run test -j1)
(cd packages/newton; pub global run tuneup check; pub run test -j1)
(cd packages/playfair; pub global run tuneup check) # No tests to run.
(cd packages/updater; pub global run tuneup check) # No tests to run.
# analyze all the Dart code in the repo
./bin/flutter analyze --flutter-repo --no-current-directory --no-current-package --congratulate
# flutter package tests
./bin/flutter test --engine-src-path bin/cache/travis
(cd packages/cassowary; pub run test -j1)
# (cd packages/flutter_sprites; ) # No tests to run.
(cd packages/flutter_tools; pub run test -j1)
(cd packages/flx; pub run test -j1)
(cd packages/newton; pub run test -j1)
# (cd packages/playfair; ) # No tests to run.
# (cd packages/updater; ) # No tests to run.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment