OLD | NEW |
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 /// Holds a couple utility functions used at various places in the system. | 5 /// Holds a couple utility functions used at various places in the system. |
6 library dev_compiler.src.utils; | 6 library dev_compiler.src.utils; |
7 | 7 |
8 import 'dart:io'; | 8 import 'dart:io'; |
9 | 9 |
10 import 'package:path/path.dart' as path; | 10 import 'package:path/path.dart' as path; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 _importsAndExportsOf(source, context).forEach(find); | 106 _importsAndExportsOf(source, context).forEach(find); |
107 results.add(source); | 107 results.add(source); |
108 } | 108 } |
109 find(start); | 109 find(start); |
110 return results; | 110 return results; |
111 } | 111 } |
112 | 112 |
113 /// Returns sources that are imported or exported in [source] (parts are | 113 /// Returns sources that are imported or exported in [source] (parts are |
114 /// excluded). | 114 /// excluded). |
115 Iterable<Source> _importsAndExportsOf(Source source, AnalysisContext context) { | 115 Iterable<Source> _importsAndExportsOf(Source source, AnalysisContext context) { |
116 var unit = parseDirectives(source.contents.data, name: source.fullName); | 116 var unit = |
| 117 parseDirectives(context.getContents(source).data, name: source.fullName); |
117 return unit.directives | 118 return unit.directives |
118 .where((d) => d is ImportDirective || d is ExportDirective) | 119 .where((d) => d is ImportDirective || d is ExportDirective) |
119 .map((d) { | 120 .map((d) { |
120 var res = ParseDartTask.resolveDirective(context, source, d, null); | 121 var res = ParseDartTask.resolveDirective(context, source, d, null); |
121 if (res == null) print('error: couldn\'t resolve $d'); | 122 if (res == null) print('error: couldn\'t resolve $d'); |
122 return res; | 123 return res; |
123 }).where((d) => d != null); | 124 }).where((d) => d != null); |
124 } | 125 } |
125 | 126 |
126 /// Returns the enclosing library of [e]. | 127 /// Returns the enclosing library of [e]. |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 } | 285 } |
285 | 286 |
286 SourceLocation locationForOffset(CompilationUnit unit, Uri uri, int offset) { | 287 SourceLocation locationForOffset(CompilationUnit unit, Uri uri, int offset) { |
287 var lineInfo = unit.lineInfo.getLocation(offset); | 288 var lineInfo = unit.lineInfo.getLocation(offset); |
288 return new SourceLocation(offset, | 289 return new SourceLocation(offset, |
289 sourceUrl: uri, | 290 sourceUrl: uri, |
290 line: lineInfo.lineNumber - 1, | 291 line: lineInfo.lineNumber - 1, |
291 column: lineInfo.columnNumber - 1); | 292 column: lineInfo.columnNumber - 1); |
292 } | 293 } |
293 | 294 |
294 // TODO(sigmund): change to show the span from the beginning of the line (#73) | |
295 SourceSpan spanForNode(CompilationUnit unit, Source source, AstNode node) { | |
296 var currentToken = node is AnnotatedNode | |
297 ? node.firstTokenAfterCommentAndMetadata | |
298 : node.beginToken; | |
299 var begin = currentToken.offset; | |
300 var end = node.end; | |
301 var text = source.contents.data.substring(begin, end); | |
302 var uri = source.uri; | |
303 return new SourceSpan(locationForOffset(unit, uri, begin), | |
304 locationForOffset(unit, uri, end), '$text'); | |
305 } | |
306 | |
307 /// Computes a hash for the given contents. | 295 /// Computes a hash for the given contents. |
308 String computeHash(String contents) { | 296 String computeHash(String contents) { |
309 if (contents == null || contents == '') return null; | 297 if (contents == null || contents == '') return null; |
310 return CryptoUtils.bytesToHex((new MD5()..add(contents.codeUnits)).close()); | 298 return CryptoUtils.bytesToHex((new MD5()..add(contents.codeUnits)).close()); |
311 } | 299 } |
312 | 300 |
313 /// Computes a hash for the given file path (reads the contents in binary form). | 301 /// Computes a hash for the given file path (reads the contents in binary form). |
314 String computeHashFromFile(String filepath) { | 302 String computeHashFromFile(String filepath) { |
315 var bytes = new File(filepath).readAsBytesSync(); | 303 var bytes = new File(filepath).readAsBytesSync(); |
316 return CryptoUtils.bytesToHex((new MD5()..add(bytes)).close()); | 304 return CryptoUtils.bytesToHex((new MD5()..add(bytes)).close()); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 InterfaceType findSupertype(InterfaceType type, bool match(InterfaceType t)) { | 420 InterfaceType findSupertype(InterfaceType type, bool match(InterfaceType t)) { |
433 for (var m in type.mixins.reversed) { | 421 for (var m in type.mixins.reversed) { |
434 if (match(m)) return m; | 422 if (match(m)) return m; |
435 } | 423 } |
436 var s = type.superclass; | 424 var s = type.superclass; |
437 if (s == null) return null; | 425 if (s == null) return null; |
438 | 426 |
439 if (match(s)) return type; | 427 if (match(s)) return type; |
440 return findSupertype(s, match); | 428 return findSupertype(s, match); |
441 } | 429 } |
| 430 |
| 431 SourceSpanWithContext createSpan( |
| 432 AnalysisContext context, CompilationUnit unit, int start, int end, |
| 433 [Source source]) { |
| 434 if (source == null) source = unit.element.source; |
| 435 var content = context.getContents(source).data; |
| 436 var startLoc = locationForOffset(unit, source.uri, start); |
| 437 var endLoc = locationForOffset(unit, source.uri, end); |
| 438 |
| 439 var lineStart = startLoc.offset - startLoc.column; |
| 440 // Find the end of the line. This is not exposed directly on LineInfo, but |
| 441 // we can find it pretty easily. |
| 442 // TODO(jmesserly): for now we do the simple linear scan. Ideally we can get |
| 443 // some help from the LineInfo API. |
| 444 var lineInfo = unit.lineInfo; |
| 445 int lineEnd = endLoc.offset; |
| 446 int unitEnd = unit.endToken.end; |
| 447 int lineNum = lineInfo.getLocation(lineEnd).lineNumber; |
| 448 while (lineEnd < unitEnd && |
| 449 lineInfo.getLocation(++lineEnd).lineNumber == lineNum); |
| 450 |
| 451 var text = content.substring(start, end); |
| 452 var lineText = content.substring(lineStart, lineEnd); |
| 453 return new SourceSpanWithContext(startLoc, endLoc, text, lineText); |
| 454 } |
OLD | NEW |