More logging.
diff --git a/lib/src/dart_formatter.dart b/lib/src/dart_formatter.dart
index 15a0415..92bd793 100644
--- a/lib/src/dart_formatter.dart
+++ b/lib/src/dart_formatter.dart
@@ -18,6 +18,7 @@
import 'constants.dart';
import 'exceptions.dart';
import 'front_end/ast_node_visitor.dart';
+import 'profile.dart';
import 'short/source_visitor.dart';
import 'short/style_fix.dart';
import 'source_code.dart';
@@ -97,104 +98,116 @@
/// Returns a new [SourceCode] containing the formatted code and the resulting
/// selection, if any.
SourceCode formatSource(SourceCode source) {
- var inputOffset = 0;
- var text = source.text;
- var unitSourceCode = source;
+ Profile.begin2('DartFormatter.formatSource()', source.uri);
+ try {
+ var inputOffset = 0;
+ var text = source.text;
+ var unitSourceCode = source;
- // If we're parsing a single statement, wrap the source in a fake function.
- if (!source.isCompilationUnit) {
- var prefix = 'void foo() { ';
- inputOffset = prefix.length;
- text = '$prefix$text }';
- unitSourceCode = SourceCode(
- text,
- uri: source.uri,
- isCompilationUnit: false,
- selectionStart: source.selectionStart != null
- ? source.selectionStart! + inputOffset
- : null,
- selectionLength: source.selectionLength,
- );
- }
-
- // Parse it.
- var parseResult = _parse(text, source.uri, patterns: true);
-
- // If we couldn't parse it with patterns enabled, it may be because of
- // one of the breaking syntax changes to switch cases. Try parsing it
- // again without patterns.
- if (parseResult.errors.isNotEmpty) {
- var withoutPatternsResult = _parse(text, source.uri, patterns: false);
-
- // If we succeeded this time, use this parse instead.
- if (withoutPatternsResult.errors.isEmpty) {
- parseResult = withoutPatternsResult;
+ // If we're parsing a single statement, wrap the source in a fake function.
+ if (!source.isCompilationUnit) {
+ var prefix = 'void foo() { ';
+ inputOffset = prefix.length;
+ text = '$prefix$text }';
+ unitSourceCode = SourceCode(
+ text,
+ uri: source.uri,
+ isCompilationUnit: false,
+ selectionStart: source.selectionStart != null
+ ? source.selectionStart! + inputOffset
+ : null,
+ selectionLength: source.selectionLength,
+ );
}
- }
- // Infer the line ending if not given one. Do it here since now we know
- // where the lines start.
- if (lineEnding == null) {
- // If the first newline is "\r\n", use that. Otherwise, use "\n".
- var lineStarts = parseResult.lineInfo.lineStarts;
- if (lineStarts.length > 1 &&
- lineStarts[1] >= 2 &&
- text[lineStarts[1] - 2] == '\r') {
- lineEnding = '\r\n';
+ // Parse it.
+ Profile.begin2('parse', source.uri);
+ ParseStringResult parseResult;
+ AstNode node;
+ try {
+ parseResult = _parse(text, source.uri, patterns: true);
+
+ // If we couldn't parse it with patterns enabled, it may be because of
+ // one of the breaking syntax changes to switch cases. Try parsing it
+ // again without patterns.
+ if (parseResult.errors.isNotEmpty) {
+ var withoutPatternsResult = _parse(text, source.uri, patterns: false);
+
+ // If we succeeded this time, use this parse instead.
+ if (withoutPatternsResult.errors.isEmpty) {
+ parseResult = withoutPatternsResult;
+ }
+ }
+
+ // Infer the line ending if not given one. Do it here since now we know
+ // where the lines start.
+ if (lineEnding == null) {
+ // If the first newline is "\r\n", use that. Otherwise, use "\n".
+ var lineStarts = parseResult.lineInfo.lineStarts;
+ if (lineStarts.length > 1 &&
+ lineStarts[1] >= 2 &&
+ text[lineStarts[1] - 2] == '\r') {
+ lineEnding = '\r\n';
+ } else {
+ lineEnding = '\n';
+ }
+ }
+
+ // Throw if there are syntactic errors.
+ var syntacticErrors = parseResult.errors.where((error) {
+ return error.errorCode.type == ErrorType.SYNTACTIC_ERROR;
+ }).toList();
+ if (syntacticErrors.isNotEmpty) {
+ throw FormatterException(syntacticErrors);
+ }
+
+ if (source.isCompilationUnit) {
+ node = parseResult.unit;
+ } else {
+ var function =
+ parseResult.unit.declarations[0] as FunctionDeclaration;
+ var body = function.functionExpression.body as BlockFunctionBody;
+ node = body.block.statements[0];
+
+ // Make sure we consumed all of the source.
+ var token = node.endToken.next!;
+ if (token.type != TokenType.CLOSE_CURLY_BRACKET) {
+ var stringSource = StringSource(text, source.uri);
+ var error = AnalysisError.tmp(
+ source: stringSource,
+ offset: token.offset - inputOffset,
+ length: math.max(token.length, 1),
+ errorCode: ParserErrorCode.UNEXPECTED_TOKEN,
+ arguments: [token.lexeme]);
+ throw FormatterException([error]);
+ }
+ }
+ } finally {
+ Profile.end2('parse', source.uri);
+ }
+
+ // Format it.
+ var lineInfo = parseResult.lineInfo;
+
+ SourceCode output;
+ if (experimentFlags.contains(tallStyleExperimentFlag)) {
+ var visitor = AstNodeVisitor(this, lineInfo, unitSourceCode);
+ output = visitor.run(node);
} else {
- lineEnding = '\n';
+ var visitor = SourceVisitor(this, lineInfo, unitSourceCode);
+ output = visitor.run(node);
}
- }
- // Throw if there are syntactic errors.
- var syntacticErrors = parseResult.errors.where((error) {
- return error.errorCode.type == ErrorType.SYNTACTIC_ERROR;
- }).toList();
- if (syntacticErrors.isNotEmpty) {
- throw FormatterException(syntacticErrors);
- }
-
- AstNode node;
- if (source.isCompilationUnit) {
- node = parseResult.unit;
- } else {
- var function = parseResult.unit.declarations[0] as FunctionDeclaration;
- var body = function.functionExpression.body as BlockFunctionBody;
- node = body.block.statements[0];
-
- // Make sure we consumed all of the source.
- var token = node.endToken.next!;
- if (token.type != TokenType.CLOSE_CURLY_BRACKET) {
- var stringSource = StringSource(text, source.uri);
- var error = AnalysisError.tmp(
- source: stringSource,
- offset: token.offset - inputOffset,
- length: math.max(token.length, 1),
- errorCode: ParserErrorCode.UNEXPECTED_TOKEN,
- arguments: [token.lexeme]);
- throw FormatterException([error]);
+ // Sanity check that only whitespace was changed if that's all we expect.
+ if (fixes.isEmpty &&
+ !string_compare.equalIgnoringWhitespace(source.text, output.text)) {
+ throw UnexpectedOutputException(source.text, output.text);
}
+
+ return output;
+ } finally {
+ Profile.end2('DartFormatter.formatSource()', source.uri);
}
-
- // Format it.
- var lineInfo = parseResult.lineInfo;
-
- SourceCode output;
- if (experimentFlags.contains(tallStyleExperimentFlag)) {
- var visitor = AstNodeVisitor(this, lineInfo, unitSourceCode);
- output = visitor.run(node);
- } else {
- var visitor = SourceVisitor(this, lineInfo, unitSourceCode);
- output = visitor.run(node);
- }
-
- // Sanity check that only whitespace was changed if that's all we expect.
- if (fixes.isEmpty &&
- !string_compare.equalIgnoringWhitespace(source.text, output.text)) {
- throw UnexpectedOutputException(source.text, output.text);
- }
-
- return output;
}
/// Parse [source] from [uri].
diff --git a/lib/src/short/source_visitor.dart b/lib/src/short/source_visitor.dart
index d5a84f8..9beb20b 100644
--- a/lib/src/short/source_visitor.dart
+++ b/lib/src/short/source_visitor.dart
@@ -122,17 +122,23 @@
SourceCode run(AstNode node) {
Profile.begin('SourceVisitor create Chunks');
+ Profile.begin2('SourceVisitor visit AST', _source.uri);
visit(node);
// Output trailing comments.
writePrecedingCommentsAndNewlines(node.endToken.next!);
+ Profile.end2('SourceVisitor visit AST', _source.uri);
+
assert(_constNesting == 0, 'Should have exited all const contexts.');
Profile.end('SourceVisitor create Chunks');
// Finish writing and return the complete result.
- return builder.end();
+ Profile.begin2('SourceVisitor format', _source.uri);
+ var result = builder.end();
+ Profile.end2('SourceVisitor format', _source.uri);
+ return result;
}
@override
diff --git a/lib/src/worker.dart b/lib/src/worker.dart
index aef5a59..343ad11 100644
--- a/lib/src/worker.dart
+++ b/lib/src/worker.dart
@@ -87,20 +87,22 @@
static WorkerFormatResponse _processFormatRequest(
_WorkerFormatRequest request) {
- var source = SourceCode(request.source, uri: request.filePath);
-
- var formatter = DartFormatter(
- indent: request.indent,
- pageWidth: request.pageWidth,
- fixes: request.fixes,
- experimentFlags: request.experimentFlags);
+ Profile.begin2('Worker._processFormatRequest()', request.filePath);
try {
- var output = formatter.formatSource(source);
+ var source = SourceCode(request.source, uri: request.filePath);
- // TODO: Temporary code to replace the actual formatting logic with some
- // other CPU-intensive task. Comment out the above line and uncomment this
- // block to try it.
- /*
+ var formatter = DartFormatter(
+ indent: request.indent,
+ pageWidth: request.pageWidth,
+ fixes: request.fixes,
+ experimentFlags: request.experimentFlags);
+ try {
+ var output = formatter.formatSource(source);
+
+ // TODO: Temporary code to replace the actual formatting logic with some
+ // other CPU-intensive task. Comment out the above line and uncomment this
+ // block to try it.
+ /*
// Do some dumb slow computation.
int fib(int n) {
if (n <= 1) return n;
@@ -112,53 +114,47 @@
var output = source;
*/
- return (
- path: request.filePath,
- text: output.text,
- isChanged: source.text != output.text,
- selectionStart: output.selectionStart,
- selectionLength: output.selectionLength
- );
- } on FormatterException catch (err) {
- // TODO: Probably want all error reporting to happen on main isolate.
- var color = Platform.operatingSystem != 'windows' &&
- stdioType(stderr) == StdioType.terminal;
+ return (
+ path: request.filePath,
+ text: output.text,
+ isChanged: source.text != output.text,
+ selectionStart: output.selectionStart,
+ selectionLength: output.selectionLength
+ );
+ } on FormatterException catch (err) {
+ // TODO: Probably want all error reporting to happen on main isolate.
+ var color = Platform.operatingSystem != 'windows' &&
+ stdioType(stderr) == StdioType.terminal;
- stderr.writeln(err.message(color: color));
- } on UnexpectedOutputException catch (err) {
- // TODO: Probably want all error reporting to happen on main isolate.
- // TODO: Should show display path.
- stderr.writeln(
- '''Hit a bug in the formatter when formatting ${request.filePath}.
+ stderr.writeln(err.message(color: color));
+ } on UnexpectedOutputException catch (err) {
+ // TODO: Probably want all error reporting to happen on main isolate.
+ // TODO: Should show display path.
+ stderr.writeln(
+ '''Hit a bug in the formatter when formatting ${request.filePath}.
$err
Please report at github.com/dart-lang/dart_style/issues.''');
- } catch (err, stack) {
- // TODO: Probably want all error reporting to happen on main isolate.
- // TODO: Should show display path.
- stderr.writeln(
- '''Hit a bug in the formatter when formatting ${request.filePath}.
+ } catch (err, stack) {
+ // TODO: Probably want all error reporting to happen on main isolate.
+ // TODO: Should show display path.
+ stderr.writeln(
+ '''Hit a bug in the formatter when formatting ${request.filePath}.
Please report at github.com/dart-lang/dart_style/issues.
$err
$stack''');
+ }
+
+ // TODO: Temp.
+ return (
+ path: request.filePath,
+ text: 'ERROR',
+ isChanged: false,
+ selectionStart: null,
+ selectionLength: null
+ );
+ } finally {
+ Profile.end2('Worker._processFormatRequest()', request.filePath);
}
-
- // TODO: Temp.
- return (
- path: request.filePath,
- text: 'ERROR',
- isChanged: false,
- selectionStart: null,
- selectionLength: null
- );
-
- // } on FormatterException catch (err) {
- // // TODO: Color?
- // return (_ErrorType.formatter, err.message());
- // } on UnexpectedOutputException catch (err) {
- // return (_ErrorType.unexpectedOutput, err.toString());
- // } catch (err, stack) {
- // return (_ErrorType.other, '$err\n$stack');
- // }
}
final int _id;
diff --git a/tool/time.dart b/tool/time.dart
index d6487c0..600917c 100644
--- a/tool/time.dart
+++ b/tool/time.dart
@@ -23,7 +23,11 @@
var time = int.parse(match[1]!);
var label = match[2]!;
- var start = starts.remove(label)!;
+ var start = starts.remove(label);
+ if (start == null) {
+ print('No start for "$label"');
+ throw '!';
+ }
var elapsed = time - start;
var kind = label;
@@ -36,8 +40,21 @@
}
}
+ var tracked = [
+ // Nested:
+ 'format everything',
+ 'request and wait for format',
+ 'Worker._processFormatRequest()',
+ // 'DartFormatter.formatSource()',
+ // Sequential:
+ // 'parse',
+ // 'SourceVisitor visit AST',
+ // 'SourceVisitor format',
+ ];
+ var trackedTimes = <String, double>{};
+
var kinds = cumulative.keys.toList();
- kinds.sort((a, b) => cumulative[a]!.compareTo(cumulative[b]!));
+ kinds.sort();
for (var kind in kinds) {
var time = cumulative[kind]!;
var total = (time / 1000).toStringAsFixed(3).padLeft(12);
@@ -49,5 +66,16 @@
line += ', $count count ave $each';
}
print(line);
+
+ if (tracked.contains(kind)) {
+ trackedTimes[kind] = time / 1000;
+ }
}
+
+ print(tracked.map((t) => '"$t"').join(','));
+ var trackedTimesSorted = <double>[];
+ for (var kind in tracked) {
+ trackedTimesSorted.add(trackedTimes[kind]!);
+ }
+ print(trackedTimesSorted.map((t) => '"$t"').join(','));
}