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

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

Issue 1001563003: Fix in multi-package-resolver to support files that will be created later (graph (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 9 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 | « no previous file | lib/src/testing.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; 8 import 'dart:collection' show HashSet;
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,
14 CompilationUnit,
15 ExportDirective,
16 Identifier,
17 ImportDirective,
13 LibraryDirective, 18 LibraryDirective,
14 ImportDirective,
15 ExportDirective,
16 PartDirective, 19 PartDirective,
17 PartOfDirective, 20 PartOfDirective;
18 CompilationUnit,
19 Identifier;
20 import 'package:analyzer/src/generated/engine.dart' 21 import 'package:analyzer/src/generated/engine.dart'
21 show ParseDartTask, AnalysisContext; 22 show ParseDartTask, AnalysisContext;
22 import 'package:analyzer/src/generated/source.dart' show Source, SourceKind; 23 import 'package:analyzer/src/generated/source.dart' show Source, SourceKind;
23 import 'package:html5lib/dom.dart' show Document; 24 import 'package:html5lib/dom.dart' show Document, Node;
24 import 'package:html5lib/parser.dart' as html; 25 import 'package:html5lib/parser.dart' as html;
25 import 'package:logging/logging.dart' show Level; 26 import 'package:logging/logging.dart' show Level;
26 import 'package:path/path.dart' as path; 27 import 'package:path/path.dart' as path;
27 import 'package:source_span/source_span.dart' show SourceSpan; 28 import 'package:source_span/source_span.dart' show SourceSpan;
28 29
29 import 'info.dart'; 30 import 'info.dart';
30 import 'options.dart'; 31 import 'options.dart';
31 import 'report.dart'; 32 import 'report.dart';
32 import 'utils.dart'; 33 import 'utils.dart';
33 34
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 } 66 }
66 } 67 }
67 68
68 /// A node in the import graph representing a source file. 69 /// A node in the import graph representing a source file.
69 abstract class SourceNode { 70 abstract class SourceNode {
70 /// Resolved URI for this node. 71 /// Resolved URI for this node.
71 final Uri uri; 72 final Uri uri;
72 73
73 /// Resolved source from the analyzer. We let the analyzer internally track 74 /// Resolved source from the analyzer. We let the analyzer internally track
74 /// for modifications to the source files. 75 /// for modifications to the source files.
75 final Source source; 76 Source _source;
77 Source get source => _source;
76 78
77 /// Last stamp read from `source.modificationStamp`. 79 /// Last stamp read from `source.modificationStamp`.
78 int _lastStamp = 0; 80 int _lastStamp = 0;
79 81
80 /// A hash used to help browsers cache the output that would be produced from 82 /// A hash used to help browsers cache the output that would be produced from
81 /// building this node. 83 /// building this node.
82 String cachingHash; 84 String cachingHash;
83 85
84 /// Whether we need to rebuild this source file. 86 /// Whether we need to rebuild this source file.
85 bool needsRebuild = false; 87 bool needsRebuild = false;
86 88
87 /// Whether the structure of dependencies from this node (scripts, imports, 89 /// Whether the structure of dependencies from this node (scripts, imports,
88 /// exports, or parts) changed after we reparsed its contents. 90 /// exports, or parts) changed after we reparsed its contents.
89 bool structureChanged = false; 91 bool structureChanged = false;
90 92
91 /// Direct dependencies in the [SourceGraph]. These include script tags for 93 /// Direct dependencies in the [SourceGraph]. These include script tags for
92 /// [HtmlSourceNode]s; and imports, exports and parts for [DartSourceNode]s. 94 /// [HtmlSourceNode]s; and imports, exports and parts for [DartSourceNode]s.
93 Iterable<SourceNode> get allDeps => const []; 95 Iterable<SourceNode> get allDeps => const [];
94 96
95 /// Like [allDeps] but excludes parts for [DartSourceNode]s. For many 97 /// Like [allDeps] but excludes parts for [DartSourceNode]s. For many
96 /// operations we mainly care about dependencies at the library level, so 98 /// operations we mainly care about dependencies at the library level, so
97 /// parts are excluded from this list. 99 /// parts are excluded from this list.
98 Iterable<SourceNode> get depsWithoutParts => const []; 100 Iterable<SourceNode> get depsWithoutParts => const [];
99 101
100 SourceNode(this.uri, this.source); 102 SourceNode(this.uri, this._source);
101 103
102 /// Check for whether the file has changed and, if so, mark [needsRebuild] and 104 /// Check for whether the file has changed and, if so, mark [needsRebuild] and
103 /// [structureChanged] as necessary. 105 /// [structureChanged] as necessary.
104 void update(SourceGraph graph) { 106 void update(SourceGraph graph) {
105 int newStamp = source.modificationStamp; 107 if (_source == null) {
108 _source = graph._context.sourceFactory.forUri(Uri.encodeFull('$uri'));
109 if (_source == null) return;
110 }
111 int newStamp = _source.modificationStamp;
106 if (newStamp > _lastStamp) { 112 if (newStamp > _lastStamp) {
107 _lastStamp = newStamp; 113 _lastStamp = newStamp;
108 needsRebuild = true; 114 needsRebuild = true;
109 } 115 }
110 } 116 }
111 117
112 String toString() { 118 String toString() {
113 var simpleUri = uri.scheme == 'file' ? path.relative(uri.path) : "$uri"; 119 var simpleUri = uri.scheme == 'file' ? path.relative(uri.path) : "$uri";
114 return '[$runtimeType: $simpleUri]'; 120 return '[$runtimeType: $simpleUri]';
115 } 121 }
(...skipping 30 matching lines...) Expand all
146 void update(SourceGraph graph) { 152 void update(SourceGraph graph) {
147 super.update(graph); 153 super.update(graph);
148 if (needsRebuild) { 154 if (needsRebuild) {
149 graph._reporter.clearHtml(uri); 155 graph._reporter.clearHtml(uri);
150 document = html.parse(source.contents.data, generateSpans: true); 156 document = html.parse(source.contents.data, generateSpans: true);
151 var newScripts = new Set<DartSourceNode>(); 157 var newScripts = new Set<DartSourceNode>();
152 var tags = document.querySelectorAll('script[type="application/dart"]'); 158 var tags = document.querySelectorAll('script[type="application/dart"]');
153 for (var script in tags) { 159 for (var script in tags) {
154 var src = script.attributes['src']; 160 var src = script.attributes['src'];
155 if (src == null) { 161 if (src == null) {
156 graph._reporter.enterHtml(source.uri); 162 _reportError(graph, 'inlined script tags not supported at this time '
157 graph._reporter.log(new DependencyGraphError(
158 'inlined script tags not supported at this time '
159 '(see https://github.com/dart-lang/dart-dev-compiler/issues/54).', 163 '(see https://github.com/dart-lang/dart-dev-compiler/issues/54).',
160 script.sourceSpan)); 164 script);
161 graph._reporter.leaveHtml();
162 continue; 165 continue;
163 } 166 }
164 var node = graph.nodeFromUri(uri.resolve(src)); 167 var node = graph.nodeFromUri(uri.resolve(src));
165 if (node == null || !node.source.exists()) { 168 if (node == null || !node.source.exists()) {
166 graph._reporter.enterHtml(source.uri); 169 _reportError(graph, 'Script file $src not found', script);
167 graph._reporter.log(new DependencyGraphError(
168 'Script file $src not found', script.sourceSpan));
169 graph._reporter.leaveHtml();
170 } 170 }
171 if (node != null) newScripts.add(node); 171 if (node != null) newScripts.add(node);
172 } 172 }
173 173
174 if (!_same(newScripts, scripts)) { 174 if (!_same(newScripts, scripts)) {
175 structureChanged = true; 175 structureChanged = true;
176 scripts = newScripts; 176 scripts = newScripts;
177 } 177 }
178 } 178 }
179 } 179 }
180
181 void _reportError(SourceGraph graph, String message, Node node) {
182 graph._reporter.enterHtml(source.uri);
183 graph._reporter.log(new DependencyGraphError(message, node.sourceSpan));
184 graph._reporter.leaveHtml();
185 }
180 } 186 }
181 187
182 /// A node representing a Dart library or part. 188 /// A node representing a Dart library or part.
183 class DartSourceNode extends SourceNode { 189 class DartSourceNode extends SourceNode {
184 /// Set of imported libraries (empty for part files). 190 /// Set of imported libraries (empty for part files).
185 Set<DartSourceNode> imports = new Set<DartSourceNode>(); 191 Set<DartSourceNode> imports = new Set<DartSourceNode>();
186 192
187 /// Set of exported libraries (empty for part files). 193 /// Set of exported libraries (empty for part files).
188 Set<DartSourceNode> exports = new Set<DartSourceNode>(); 194 Set<DartSourceNode> exports = new Set<DartSourceNode>();
189 195
(...skipping 23 matching lines...) Expand all
213 // If the defining compilation-unit changed, the structure might have 219 // If the defining compilation-unit changed, the structure might have
214 // changed. 220 // changed.
215 var unit = parseDirectives(source.contents.data, name: source.fullName); 221 var unit = parseDirectives(source.contents.data, name: source.fullName);
216 var newImports = new Set<DartSourceNode>(); 222 var newImports = new Set<DartSourceNode>();
217 var newExports = new Set<DartSourceNode>(); 223 var newExports = new Set<DartSourceNode>();
218 var newParts = new Set<DartSourceNode>(); 224 var newParts = new Set<DartSourceNode>();
219 for (var d in unit.directives) { 225 for (var d in unit.directives) {
220 // Nothing to do for parts. 226 // Nothing to do for parts.
221 if (d is PartOfDirective) return; 227 if (d is PartOfDirective) return;
222 if (d is LibraryDirective) continue; 228 if (d is LibraryDirective) continue;
229
230 // `dart:core` and other similar URLs only contain a name, but it is
231 // meant to be a folder when resolving relative paths from it.
232 var targetUri = uri.scheme == 'dart' && uri.pathSegments.length == 1
233 ? Uri.parse('$uri/').resolve(d.uri.stringValue)
234 : uri.resolve(d.uri.stringValue);
223 var target = 235 var target =
224 ParseDartTask.resolveDirective(graph._context, source, d, null); 236 ParseDartTask.resolveDirective(graph._context, source, d, null);
225 var uri = target.uri; 237 if (target != null) {
226 var node = 238 if (targetUri != target.uri) print(">> ${target.uri} $targetUri");
227 graph.nodes.putIfAbsent(uri, () => new DartSourceNode(uri, target)); 239 }
228 if (!node.source.exists()) { 240 var node = graph.nodes.putIfAbsent(
229 graph._reporter.enterLibrary(source.uri); 241 targetUri, () => new DartSourceNode(targetUri, target));
230 graph._reporter.log(new DependencyGraphError( 242 //var node = graph.nodeFromUri(targetUri);
231 'File $uri not found', spanForNode(unit, source, d))); 243 if (node.source == null || !node.source.exists()) {
232 graph._reporter.leaveLibrary(); 244 _reportError(graph, 'File $targetUri not found', unit, d);
233 } 245 }
234 246
235 if (d is ImportDirective) { 247 if (d is ImportDirective) {
236 newImports.add(node); 248 newImports.add(node);
237 } else if (d is ExportDirective) { 249 } else if (d is ExportDirective) {
238 newExports.add(node); 250 newExports.add(node);
239 } else if (d is PartDirective) { 251 } else if (d is PartDirective) {
240 newParts.add(node); 252 newParts.add(node);
241 } 253 }
242 } 254 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 // internally: 287 // internally:
276 for (var p in parts) { 288 for (var p in parts) {
277 // Technically for parts we don't need to look at the contents. If they 289 // Technically for parts we don't need to look at the contents. If they
278 // contain imports, exports, or parts, we'll ignore them in our crawling. 290 // contain imports, exports, or parts, we'll ignore them in our crawling.
279 // However we do a full update to make it easier to adjust when users 291 // However we do a full update to make it easier to adjust when users
280 // switch a file from a part to a library. 292 // switch a file from a part to a library.
281 p.update(graph); 293 p.update(graph);
282 if (p.needsRebuild) needsRebuild = true; 294 if (p.needsRebuild) needsRebuild = true;
283 } 295 }
284 } 296 }
297
298 void _reportError(
299 SourceGraph graph, String message, CompilationUnit unit, AstNode node) {
300 graph._reporter.enterLibrary(source.uri);
301 graph._reporter.log(
302 new DependencyGraphError(message, spanForNode(unit, source, node)));
303 graph._reporter.leaveLibrary();
304 }
285 } 305 }
286 306
287 /// Represents a runtime resource from our compiler that is needed to run an 307 /// Represents a runtime resource from our compiler that is needed to run an
288 /// application. 308 /// application.
289 class ResourceSourceNode extends SourceNode { 309 class ResourceSourceNode extends SourceNode {
290 ResourceSourceNode(uri, source) : super(uri, source); 310 ResourceSourceNode(uri, source) : super(uri, source);
291 } 311 }
292 312
293 /// Updates the structure and `needsRebuild` marks in nodes of [graph] reachable 313 /// Updates the structure and `needsRebuild` marks in nodes of [graph] reachable
294 /// from [start]. 314 /// from [start].
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 helper(start); 428 helper(start);
409 } 429 }
410 430
411 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b); 431 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b);
412 432
413 /// An error message discovered while parsing the dependencies between files. 433 /// An error message discovered while parsing the dependencies between files.
414 class DependencyGraphError extends MessageWithSpan { 434 class DependencyGraphError extends MessageWithSpan {
415 const DependencyGraphError(String message, SourceSpan span) 435 const DependencyGraphError(String message, SourceSpan span)
416 : super(message, Level.SEVERE, span); 436 : super(message, Level.SEVERE, span);
417 } 437 }
OLDNEW
« no previous file with comments | « no previous file | lib/src/testing.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698