| 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 |