Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(589)

Side by Side Diff: lib/src/report.dart

Issue 1141013002: Fixes #179 -- compile error if editing files during server mode (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// Summarizes the information produced by the checker. 5 /// Summarizes the information produced by the checker.
6 library dev_compiler.src.report; 6 library dev_compiler.src.report;
7 7
8 import 'dart:math' show max; 8 import 'dart:math' show max;
9 9
10 import 'package:analyzer/src/generated/ast.dart' show AstNode, CompilationUnit;
11 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
10 import 'package:analyzer/src/generated/source.dart' show Source; 12 import 'package:analyzer/src/generated/source.dart' show Source;
11 import 'package:logging/logging.dart'; 13 import 'package:logging/logging.dart';
12 import 'package:path/path.dart' as path; 14 import 'package:path/path.dart' as path;
13 import 'package:source_span/source_span.dart'; 15 import 'package:source_span/source_span.dart';
14 16
15 import 'info.dart'; 17 import 'info.dart';
16 import 'utils.dart'; 18 import 'utils.dart';
17 import 'summary.dart'; 19 import 'summary.dart';
18 20
19 /// A message (error or warning) produced by the dev_compiler and it's location 21 /// A message (error or warning) produced by the dev_compiler and it's location
20 /// information. 22 /// information.
21 /// 23 ///
22 /// Currently the location information includes only the offsets within a file 24 /// Currently the location information includes only the offsets within a file
23 /// where the error occurs. This is used in the context of a [CheckerReporter], 25 /// where the error occurs. This is used in the context of a [CheckerReporter],
24 /// where the current file is being tracked. 26 /// where the current file is being tracked.
25 abstract class Message { 27 class Message {
26 // Message description. 28 // Message description.
27 final String message; 29 final String message;
28 30
29 /// Log level. This is a placeholder for severity. 31 /// Log level. This is a placeholder for severity.
30 final Level level; 32 final Level level;
31 33
32 /// Offset where the error message begins in the tracked source file. 34 /// Offset where the error message begins in the tracked source file.
33 final int begin; 35 final int begin;
34 36
35 /// Offset where the error message ends in the tracked source file. 37 /// Offset where the error message ends in the tracked source file.
36 final int end; 38 final int end;
37 39
38 const Message(this.message, this.level, this.begin, this.end); 40 const Message(this.message, this.level, this.begin, this.end);
39 } 41 }
40 42
41 /// Like [Message], but with a precomputed source span.
42 abstract class MessageWithSpan implements Message {
43 final String message;
44
45 final Level level;
46
47 final SourceSpan span;
48
49 int get begin => span.start.offset;
50 int get end => span.end.offset;
51
52 const MessageWithSpan(this.message, this.level, this.span);
53 }
54
55 // Interface used to report error messages from the checker. 43 // Interface used to report error messages from the checker.
56 abstract class CheckerReporter { 44 abstract class CheckerReporter {
45 final AnalysisContext _context;
46 CompilationUnit _unit;
47 Source _unitSource;
48
49 CheckerReporter(this._context);
50
57 /// Called when starting to process a library. 51 /// Called when starting to process a library.
58 void enterLibrary(Uri uri); 52 void enterLibrary(Uri uri);
59 void leaveLibrary(); 53 void leaveLibrary();
60 54
61 /// Called when starting to process an HTML source file. 55 /// Called when starting to process an HTML source file.
62 void enterHtml(Uri uri); 56 void enterHtml(Uri uri);
63 void leaveHtml(); 57 void leaveHtml();
64 58
65 /// Called when starting to process a source. All subsequent log entries must 59 /// Called when starting to process a source. All subsequent log entries must
66 /// belong to this source until the next call to enterSource. 60 /// belong to this source until the next call to enterSource.
67 void enterSource(Source source); 61 void enterCompilationUnit(CompilationUnit unit, [Source source]) {
68 void leaveSource(); 62 _unit = unit;
63 _unitSource = source;
64 }
65 void leaveCompilationUnit() {
66 _unit = null;
67 _unitSource = null;
68 }
69
69 void log(Message message); 70 void log(Message message);
70 71
71 // Called in server-mode. 72 // Called in server-mode.
72 void clearLibrary(Uri uri); 73 void clearLibrary(Uri uri);
73 void clearHtml(Uri uri); 74 void clearHtml(Uri uri);
74 void clearAll(); 75 void clearAll();
76
77 SourceSpanWithContext _createSpan(int start, int end) =>
78 createSpan(_context, _unit, start, end, _unitSource);
75 } 79 }
76 80
77 final _checkerLogger = new Logger('dev_compiler.checker'); 81 final _checkerLogger = new Logger('dev_compiler.checker');
78 82
79 /// Simple reporter that logs checker messages as they are seen. 83 /// Simple reporter that logs checker messages as they are seen.
80 class LogReporter implements CheckerReporter { 84 class LogReporter extends CheckerReporter {
81 final bool useColors; 85 final bool useColors;
82 SourceFile _file;
83 Source _current; 86 Source _current;
84 87
85 LogReporter([this.useColors = false]); 88 LogReporter(AnalysisContext context, {this.useColors: false})
89 : super(context);
86 90
87 void enterLibrary(Uri uri) {} 91 void enterLibrary(Uri uri) {}
88 void leaveLibrary() {} 92 void leaveLibrary() {}
89 93
90 void enterHtml(Uri uri) {} 94 void enterHtml(Uri uri) {}
91 void leaveHtml() {} 95 void leaveHtml() {}
92 96
93 void enterSource(Source source) {
94 _file = new SourceFile(source.contents.data, url: source.uri);
95 _current = source;
96 }
97
98 void leaveSource() {
99 _file = null;
100 _current = null;
101 }
102
103 void log(Message message) { 97 void log(Message message) {
104 if (message is StaticInfo) { 98 if (message is StaticInfo) {
105 assert((message.node as dynamic).root.element.source == _current); 99 assert(message.node.root == _unit);
106 } 100 }
107 // TODO(sigmund): convert to use span information from AST (issue #73) 101 // TODO(sigmund): convert to use span information from AST (issue #73)
108 final span = message is MessageWithSpan 102 final span = _createSpan(message.begin, message.end);
109 ? message.span
110 : _file.span(message.begin, message.end);
111 final level = message.level; 103 final level = message.level;
112 final color = useColors ? colorOf(level.name) : null; 104 final color = useColors ? colorOf(level.name) : null;
113 final text = '[${message.runtimeType}] ${message.message}'; 105 final text = '[${message.runtimeType}] ${message.message}';
114 _checkerLogger.log(level, span.message(text, color: color)); 106 _checkerLogger.log(level, span.message(text, color: color));
115 } 107 }
116 108
117 void clearLibrary(Uri uri) {} 109 void clearLibrary(Uri uri) {}
118 void clearHtml(Uri uri) {} 110 void clearHtml(Uri uri) {}
119 void clearAll() {} 111 void clearAll() {}
120 } 112 }
121 113
122 /// A reporter that gathers all the information in a [GlobalSummary]. 114 /// A reporter that gathers all the information in a [GlobalSummary].
123 class SummaryReporter implements CheckerReporter { 115 class SummaryReporter extends CheckerReporter {
124 GlobalSummary result = new GlobalSummary(); 116 GlobalSummary result = new GlobalSummary();
125 IndividualSummary _current; 117 IndividualSummary _current;
126 SourceFile _file; 118
119 SummaryReporter(AnalysisContext context) : super(context);
127 120
128 void enterLibrary(Uri uri) { 121 void enterLibrary(Uri uri) {
129 var container; 122 var container;
130 if (uri.scheme == 'package') { 123 if (uri.scheme == 'package') {
131 var pname = path.split(uri.path)[0]; 124 var pname = path.split(uri.path)[0];
132 result.packages.putIfAbsent(pname, () => new PackageSummary(pname)); 125 result.packages.putIfAbsent(pname, () => new PackageSummary(pname));
133 container = result.packages[pname].libraries; 126 container = result.packages[pname].libraries;
134 } else if (uri.scheme == 'dart') { 127 } else if (uri.scheme == 'dart') {
135 container = result.system; 128 container = result.system;
136 } else { 129 } else {
137 container = result.loose; 130 container = result.loose;
138 } 131 }
139 _current = container.putIfAbsent('$uri', () => new LibrarySummary('$uri')); 132 _current = container.putIfAbsent('$uri', () => new LibrarySummary('$uri'));
140 } 133 }
141 134
142 void leaveLibrary() { 135 void leaveLibrary() {
143 _current = null; 136 _current = null;
144 } 137 }
145 138
146 void enterHtml(Uri uri) { 139 void enterHtml(Uri uri) {
147 _current = result.loose.putIfAbsent('$uri', () => new HtmlSummary('$uri')); 140 _current = result.loose.putIfAbsent('$uri', () => new HtmlSummary('$uri'));
148 } 141 }
149 142
150 void leaveHtml() { 143 void leaveHtml() {
151 _current = null; 144 _current = null;
152 } 145 }
153 146
154 void enterSource(Source source) { 147 @override
155 _file = new SourceFile(source.contents.data, url: source.uri); 148 void enterCompilationUnit(CompilationUnit unit, [Source source]) {
149 super.enterCompilationUnit(unit, source);
156 if (_current is LibrarySummary) { 150 if (_current is LibrarySummary) {
157 (_current as LibrarySummary).lines += _file.lines; 151 int lines = _unit.lineInfo.getLocation(_unit.endToken.end).lineNumber;
152 (_current as LibrarySummary).lines += lines;
158 } 153 }
159 } 154 }
160 155
161 void leaveSource() {
162 _file = null;
163 }
164
165 void log(Message message) { 156 void log(Message message) {
166 assert(message is MessageWithSpan || _file != null); 157 final span = _createSpan(message.begin, message.end);
167 // TODO(sigmund): convert to use span information from AST (issue #73)
168 final span = message is MessageWithSpan
169 ? message.span
170 : _file.span(message.begin, message.end);
171 _current.messages.add(new MessageSummary('${message.runtimeType}', 158 _current.messages.add(new MessageSummary('${message.runtimeType}',
172 message.level.name.toLowerCase(), span, message.message)); 159 message.level.name.toLowerCase(), span, message.message));
173 } 160 }
174 161
175 void clearLibrary(Uri uri) { 162 void clearLibrary(Uri uri) {
176 enterLibrary(uri); 163 enterLibrary(uri);
177 _current.messages.clear(); 164 _current.messages.clear();
178 (_current as LibrarySummary).lines = 0; 165 (_current as LibrarySummary).lines = 0;
179 leaveLibrary(); 166 leaveLibrary();
180 } 167 }
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 368
382 visitMessage(MessageSummary message) { 369 visitMessage(MessageSummary message) {
383 var kind = message.kind; 370 var kind = message.kind;
384 errorCount.putIfAbsent(currentPackage, () => <String, int>{}); 371 errorCount.putIfAbsent(currentPackage, () => <String, int>{});
385 errorCount[currentPackage].putIfAbsent(kind, () => 0); 372 errorCount[currentPackage].putIfAbsent(kind, () => 0);
386 errorCount[currentPackage][kind]++; 373 errorCount[currentPackage][kind]++;
387 totals.putIfAbsent(kind, () => 0); 374 totals.putIfAbsent(kind, () => 0);
388 totals[kind]++; 375 totals[kind]++;
389 } 376 }
390 } 377 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698