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

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

Issue 1230903002: fixes #6, refactor to use AnalysisError/Listener throughout dev_compiler (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 5 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
« no previous file with comments | « lib/src/codegen/js_printer.dart ('k') | lib/src/info.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /// Tracks the shape of the import/export graph and dependencies between files. 5 /// Tracks the shape of the import/export graph and dependencies between files.
6 library dev_compiler.src.dependency_graph; 6 library dev_compiler.src.dependency_graph;
7 7
8 import 'dart:collection' show HashSet, HashMap; 8 import 'dart:collection' show HashSet, HashMap;
9 9
10 import 'package:analyzer/analyzer.dart' show parseDirectives; 10 import 'package:analyzer/analyzer.dart' show parseDirectives;
11 import 'package:analyzer/src/generated/ast.dart' 11 import 'package:analyzer/src/generated/ast.dart'
12 show 12 show
13 AstNode, 13 AstNode,
14 CompilationUnit, 14 CompilationUnit,
15 ExportDirective, 15 ExportDirective,
16 Identifier, 16 Identifier,
17 ImportDirective, 17 ImportDirective,
18 LibraryDirective, 18 LibraryDirective,
19 PartDirective, 19 PartDirective,
20 PartOfDirective, 20 PartOfDirective,
21 UriBasedDirective; 21 UriBasedDirective;
22 import 'package:analyzer/src/generated/engine.dart' 22 import 'package:analyzer/src/generated/engine.dart'
23 show ParseDartTask, AnalysisContext; 23 show ParseDartTask, AnalysisContext;
24 import 'package:analyzer/src/generated/error.dart';
24 import 'package:analyzer/src/generated/source.dart' show Source, SourceKind; 25 import 'package:analyzer/src/generated/source.dart' show Source, SourceKind;
25 import 'package:html/dom.dart' show Document, Node, Element; 26 import 'package:html/dom.dart' show Document, Node, Element;
26 import 'package:html/parser.dart' as html; 27 import 'package:html/parser.dart' as html;
27 import 'package:logging/logging.dart' show Logger, Level; 28 import 'package:logging/logging.dart' show Logger, Level;
28 import 'package:path/path.dart' as path; 29 import 'package:path/path.dart' as path;
29 30
30 import 'info.dart'; 31 import 'info.dart';
31 import 'options.dart'; 32 import 'options.dart';
32 import 'report.dart'; 33 import 'report.dart';
33 34
34 /// Holds references to all source nodes in the import graph. This is mainly 35 /// Holds references to all source nodes in the import graph. This is mainly
35 /// used as a level of indirection to ensure that each source has a canonical 36 /// used as a level of indirection to ensure that each source has a canonical
36 /// representation. 37 /// representation.
37 class SourceGraph { 38 class SourceGraph {
38 /// All nodes in the source graph. Used to get a canonical representation for 39 /// All nodes in the source graph. Used to get a canonical representation for
39 /// any node. 40 /// any node.
40 final Map<Uri, SourceNode> nodes = {}; 41 final Map<Uri, SourceNode> nodes = {};
41 42
42 /// Resources included by default on any application. 43 /// Resources included by default on any application.
43 final runtimeDeps = new Set<ResourceSourceNode>(); 44 final runtimeDeps = new Set<ResourceSourceNode>();
44 45
45 /// Analyzer used to resolve source files. 46 /// Analyzer used to resolve source files.
46 final AnalysisContext _context; 47 final AnalysisContext _context;
47 final CompilerReporter _reporter; 48 final AnalysisErrorListener _reporter;
48 final CompilerOptions _options; 49 final CompilerOptions _options;
49 50
50 SourceGraph(this._context, this._reporter, this._options) { 51 SourceGraph(this._context, this._reporter, this._options) {
51 var dir = _options.runtimeDir; 52 var dir = _options.runtimeDir;
52 if (dir == null) { 53 if (dir == null) {
53 _log.severe('Runtime dir could not be determined automatically, ' 54 _log.severe('Runtime dir could not be determined automatically, '
54 'please specify the --runtime-dir flag on the command line.'); 55 'please specify the --runtime-dir flag on the command line.');
55 return; 56 return;
56 } 57 }
57 var prefix = path.absolute(dir); 58 var prefix = path.absolute(dir);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 final htmlResourceNodes = new HashMap<Element, ResourceSourceNode>(); 175 final htmlResourceNodes = new HashMap<Element, ResourceSourceNode>();
175 176
176 HtmlSourceNode(SourceGraph graph, Uri uri, Source source) 177 HtmlSourceNode(SourceGraph graph, Uri uri, Source source)
177 : runtimeDeps = graph.runtimeDeps, 178 : runtimeDeps = graph.runtimeDeps,
178 super(graph, uri, source); 179 super(graph, uri, source);
179 180
180 @override 181 @override
181 void update() { 182 void update() {
182 super.update(); 183 super.update();
183 if (needsRebuild) { 184 if (needsRebuild) {
184 graph._reporter.clearHtml(uri); 185 var reporter = graph._reporter;
186 if (reporter is SummaryReporter) {
187 reporter.clearHtml(uri);
188 }
185 document = html.parse(contents, generateSpans: true); 189 document = html.parse(contents, generateSpans: true);
186 var newScripts = new Set<DartSourceNode>(); 190 var newScripts = new Set<DartSourceNode>();
187 var tags = document.querySelectorAll('script[type="application/dart"]'); 191 var tags = document.querySelectorAll('script[type="application/dart"]');
188 for (var script in tags) { 192 for (var script in tags) {
189 var src = script.attributes['src']; 193 var src = script.attributes['src'];
190 if (src == null) { 194 if (src == null) {
191 _reportError(graph, 'inlined script tags not supported at this time ' 195 _reportError(graph, 'inlined script tags not supported at this time '
192 '(see https://github.com/dart-lang/dart-dev-compiler/issues/54).', 196 '(see https://github.com/dart-lang/dart-dev-compiler/issues/54).',
193 script); 197 script);
194 continue; 198 continue;
(...skipping 30 matching lines...) Expand all
225 newResources.add(res); 229 newResources.add(res);
226 } 230 }
227 if (!_same(newResources, resources)) { 231 if (!_same(newResources, resources)) {
228 structureChanged = true; 232 structureChanged = true;
229 resources = newResources; 233 resources = newResources;
230 } 234 }
231 } 235 }
232 } 236 }
233 237
234 void _reportError(SourceGraph graph, String message, Node node) { 238 void _reportError(SourceGraph graph, String message, Node node) {
235 graph._reporter.enterHtml(_source.uri);
236 var span = node.sourceSpan; 239 var span = node.sourceSpan;
237 graph._reporter.log( 240
238 new Message(message, Level.SEVERE, span.start.offset, span.end.offset)); 241 // TODO(jmesserly): should these be errors or warnings?
239 graph._reporter.leaveHtml(); 242 var errorCode = new HtmlWarningCode('dev_compiler.$runtimeType', message);
243 graph._reporter.onError(new AnalysisError(
244 _source, span.start.offset, span.length, errorCode));
240 } 245 }
241 } 246 }
242 247
243 /// A node representing a Dart library or part. 248 /// A node representing a Dart library or part.
244 class DartSourceNode extends SourceNode { 249 class DartSourceNode extends SourceNode {
245 /// Set of imported libraries (empty for part files). 250 /// Set of imported libraries (empty for part files).
246 Set<DartSourceNode> imports = new Set<DartSourceNode>(); 251 Set<DartSourceNode> imports = new Set<DartSourceNode>();
247 252
248 /// Set of exported libraries (empty for part files). 253 /// Set of exported libraries (empty for part files).
249 Set<DartSourceNode> exports = new Set<DartSourceNode>(); 254 Set<DartSourceNode> exports = new Set<DartSourceNode>();
(...skipping 24 matching lines...) Expand all
274 // But we could discard it after that point. 279 // But we could discard it after that point.
275 void saveUpdatedContents() { 280 void saveUpdatedContents() {
276 graph._context.setContents(_source, _source.contents.data); 281 graph._context.setContents(_source, _source.contents.data);
277 } 282 }
278 283
279 @override 284 @override
280 void update() { 285 void update() {
281 super.update(); 286 super.update();
282 287
283 if (needsRebuild) { 288 if (needsRebuild) {
284 graph._reporter.clearLibrary(uri); 289 var reporter = graph._reporter;
290 if (reporter is SummaryReporter) {
291 reporter.clearLibrary(uri);
292 }
293
285 // If the defining compilation-unit changed, the structure might have 294 // If the defining compilation-unit changed, the structure might have
286 // changed. 295 // changed.
287 var unit = parseDirectives(contents, name: _source.fullName); 296 var unit = parseDirectives(contents, name: _source.fullName);
288 var newImports = new Set<DartSourceNode>(); 297 var newImports = new Set<DartSourceNode>();
289 var newExports = new Set<DartSourceNode>(); 298 var newExports = new Set<DartSourceNode>();
290 var newParts = new Set<DartSourceNode>(); 299 var newParts = new Set<DartSourceNode>();
291 for (var d in unit.directives) { 300 for (var d in unit.directives) {
292 // Nothing to do for parts. 301 // Nothing to do for parts.
293 if (d is PartOfDirective) return; 302 if (d is PartOfDirective) return;
294 if (d is LibraryDirective) continue; 303 if (d is LibraryDirective) continue;
295 304
296 var directiveUri = (d as UriBasedDirective).uri; 305 var directiveUri = (d as UriBasedDirective).uri;
297 306
298 // `dart:core` and other similar URLs only contain a name, but it is 307 // `dart:core` and other similar URLs only contain a name, but it is
299 // meant to be a folder when resolving relative paths from it. 308 // meant to be a folder when resolving relative paths from it.
300 var targetUri = uri.scheme == 'dart' && uri.pathSegments.length == 1 309 var targetUri = uri.scheme == 'dart' && uri.pathSegments.length == 1
301 ? Uri.parse('$uri/').resolve(directiveUri.stringValue) 310 ? Uri.parse('$uri/').resolve(directiveUri.stringValue)
302 : uri.resolve(directiveUri.stringValue); 311 : uri.resolve(directiveUri.stringValue);
303 var target = 312 var target =
304 ParseDartTask.resolveDirective(graph._context, _source, d, null); 313 ParseDartTask.resolveDirective(graph._context, _source, d, null);
305 var node = graph.nodes.putIfAbsent( 314 var node = graph.nodes.putIfAbsent(
306 targetUri, () => new DartSourceNode(graph, targetUri, target)); 315 targetUri, () => new DartSourceNode(graph, targetUri, target));
307 //var node = graph.nodeFromUri(targetUri); 316 //var node = graph.nodeFromUri(targetUri);
308 if (node._source == null || !node._source.exists()) { 317 if (node._source == null || !node._source.exists()) {
309 _reportError(graph, 'File $targetUri not found', unit, d); 318 _reportError(graph, 'File $targetUri not found', d);
310 } 319 }
311 320
312 if (d is ImportDirective) { 321 if (d is ImportDirective) {
313 newImports.add(node); 322 newImports.add(node);
314 } else if (d is ExportDirective) { 323 } else if (d is ExportDirective) {
315 newExports.add(node); 324 newExports.add(node);
316 } else if (d is PartDirective) { 325 } else if (d is PartDirective) {
317 newParts.add(node); 326 newParts.add(node);
318 } 327 }
319 } 328 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 for (var p in parts) { 362 for (var p in parts) {
354 // Technically for parts we don't need to look at the contents. If they 363 // Technically for parts we don't need to look at the contents. If they
355 // contain imports, exports, or parts, we'll ignore them in our crawling. 364 // contain imports, exports, or parts, we'll ignore them in our crawling.
356 // However we do a full update to make it easier to adjust when users 365 // However we do a full update to make it easier to adjust when users
357 // switch a file from a part to a library. 366 // switch a file from a part to a library.
358 p.update(); 367 p.update();
359 if (p.needsRebuild) needsRebuild = true; 368 if (p.needsRebuild) needsRebuild = true;
360 } 369 }
361 } 370 }
362 371
363 void _reportError( 372 void _reportError(SourceGraph graph, String message, AstNode node) {
364 SourceGraph graph, String message, CompilationUnit unit, AstNode node) { 373 graph._reporter.onError(new AnalysisError(_source, node.offset,
365 graph._reporter 374 node.length, new CompileTimeErrorCode('dev_compiler.$runtimeType', messa ge)));
366 ..enterLibrary(_source.uri)
367 ..enterCompilationUnit(unit, _source)
368 ..log(new Message(message, Level.SEVERE, node.offset, node.end))
369 ..leaveCompilationUnit()
370 ..leaveLibrary();
371 } 375 }
372 } 376 }
373 377
374 /// Represents a runtime resource from our compiler that is needed to run an 378 /// Represents a runtime resource from our compiler that is needed to run an
375 /// application. 379 /// application.
376 class ResourceSourceNode extends SourceNode { 380 class ResourceSourceNode extends SourceNode {
377 ResourceSourceNode(graph, uri, source) : super(graph, uri, source); 381 ResourceSourceNode(graph, uri, source) : super(graph, uri, source);
378 } 382 }
379 383
380 /// Updates the structure and `needsRebuild` marks in nodes of [graph] reachable 384 /// Updates the structure and `needsRebuild` marks in nodes of [graph] reachable
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 // _foreign_helper is not included, as it only defines the JS builtin that 543 // _foreign_helper is not included, as it only defines the JS builtin that
540 // the compiler handles at compile time. 544 // the compiler handles at compile time.
541 ]; 545 ];
542 546
543 /// Runtime files added to applications when running in server mode. 547 /// Runtime files added to applications when running in server mode.
544 List<String> runtimeFilesForServerMode([bool includeWidget = true]) => 548 List<String> runtimeFilesForServerMode([bool includeWidget = true]) =>
545 new List<String>.from(defaultRuntimeFiles) 549 new List<String>.from(defaultRuntimeFiles)
546 ..addAll(includeWidget ? const ['messages_widget.js', 'messages.css'] : []); 550 ..addAll(includeWidget ? const ['messages_widget.js', 'messages.css'] : []);
547 551
548 final _log = new Logger('dev_compiler.dependency_graph'); 552 final _log = new Logger('dev_compiler.dependency_graph');
OLDNEW
« no previous file with comments | « lib/src/codegen/js_printer.dart ('k') | lib/src/info.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698