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 12 matching lines...) Expand all Loading... |
23 import 'package:analyzer/src/generated/constant.dart' show DartObjectImpl; | 23 import 'package:analyzer/src/generated/constant.dart' show DartObjectImpl; |
24 import 'package:analyzer/src/generated/element.dart'; | 24 import 'package:analyzer/src/generated/element.dart'; |
25 import 'package:analyzer/src/generated/engine.dart' | 25 import 'package:analyzer/src/generated/engine.dart' |
26 show ParseDartTask, AnalysisContext; | 26 show ParseDartTask, AnalysisContext; |
27 import 'package:analyzer/src/generated/error.dart' show ErrorCode; | 27 import 'package:analyzer/src/generated/error.dart' show ErrorCode; |
28 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; | 28 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; |
29 import 'package:analyzer/src/generated/source.dart' show LineInfo, Source; | 29 import 'package:analyzer/src/generated/source.dart' show LineInfo, Source; |
30 import 'package:analyzer/analyzer.dart' show parseDirectives; | 30 import 'package:analyzer/analyzer.dart' show parseDirectives; |
31 import 'package:crypto/crypto.dart' show CryptoUtils, MD5; | 31 import 'package:crypto/crypto.dart' show CryptoUtils, MD5; |
32 import 'package:source_span/source_span.dart'; | 32 import 'package:source_span/source_span.dart'; |
33 import 'package:yaml/yaml.dart'; | |
34 | 33 |
35 import 'codegen/js_names.dart' show invalidVariableName; | 34 import 'codegen/js_names.dart' show invalidVariableName; |
36 | 35 |
37 bool isDartPrivateLibrary(LibraryElement library) { | 36 bool isDartPrivateLibrary(LibraryElement library) { |
38 var uri = library.source.uri; | 37 var uri = library.source.uri; |
39 if (uri.scheme != "dart") return false; | 38 if (uri.scheme != "dart") return false; |
40 return Identifier.isPrivateName(uri.path); | 39 return Identifier.isPrivateName(uri.path); |
41 } | 40 } |
42 | 41 |
43 /// Choose a canonical name from the library element. This is safe to use as a | 42 /// Choose a canonical name from the library element. This is safe to use as a |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 if (contents == null || contents == '') return null; | 303 if (contents == null || contents == '') return null; |
305 return CryptoUtils.bytesToHex((new MD5()..add(contents.codeUnits)).close()); | 304 return CryptoUtils.bytesToHex((new MD5()..add(contents.codeUnits)).close()); |
306 } | 305 } |
307 | 306 |
308 /// Computes a hash for the given file path (reads the contents in binary form). | 307 /// Computes a hash for the given file path (reads the contents in binary form). |
309 String computeHashFromFile(String filepath) { | 308 String computeHashFromFile(String filepath) { |
310 var bytes = new File(filepath).readAsBytesSync(); | 309 var bytes = new File(filepath).readAsBytesSync(); |
311 return CryptoUtils.bytesToHex((new MD5()..add(bytes)).close()); | 310 return CryptoUtils.bytesToHex((new MD5()..add(bytes)).close()); |
312 } | 311 } |
313 | 312 |
314 String resourceOutputPath(Uri resourceUri, Uri entryUri) { | 313 String resourceOutputPath(Uri resourceUri, Uri entryUri, String runtimeDir) { |
315 if (resourceUri.scheme == 'package') return resourceUri.path; | 314 if (resourceUri.scheme == 'package') return resourceUri.path; |
316 | 315 |
317 if (resourceUri.scheme != 'file') return null; | 316 if (resourceUri.scheme != 'file') return null; |
318 var filepath = resourceUri.path; | |
319 var relativePath = path.relative(filepath, from: path.dirname(entryUri.path)); | |
320 | 317 |
321 // File:/// urls can be for resources in the same project or resources from | 318 var entryDir = path.dirname(entryUri.path); |
322 // the dev_compiler package. For now we only support relative paths going | 319 var filepath = path.normalize(path.join(entryDir, resourceUri.path)); |
323 // further inside the folder where the entrypoint is located, otherwise we | 320 if (path.isWithin(runtimeDir, filepath)) { |
324 // assume this is a runtime resource from the dev_compiler. | 321 filepath = path.relative(filepath, from: runtimeDir); |
325 if (!relativePath.startsWith('..')) return relativePath; | 322 return path.join('dev_compiler', 'runtime', filepath); |
| 323 } |
326 | 324 |
327 // Since this is a URI path we can assume forward slash and use lastIndexOf. | 325 return path.relative(resourceUri.path, from: entryDir); |
328 var runtimePath = '/lib/runtime/'; | |
329 var pos = filepath.lastIndexOf(runtimePath); | |
330 if (pos == -1) return null; | |
331 | |
332 var filename = filepath.substring(pos + runtimePath.length); | |
333 var dir = filepath.substring(0, pos); | |
334 | |
335 // TODO(jmesserly): can we implement this without repeatedly reading pubspec? | |
336 // It seems like we should know our package's root directory without needing | |
337 // to search like this. | |
338 var pubspec = | |
339 loadYaml(new File(path.join(dir, 'pubspec.yaml')).readAsStringSync()); | |
340 | |
341 // Ensure this is loaded from the dev_compiler package. | |
342 if (pubspec['name'] != 'dev_compiler') return null; | |
343 return path.join('dev_compiler', 'runtime', filename); | |
344 } | 326 } |
345 | 327 |
346 /// Given an annotated [node] and a [test] function, returns the first matching | 328 /// Given an annotated [node] and a [test] function, returns the first matching |
347 /// constant valued annotation. | 329 /// constant valued annotation. |
348 /// | 330 /// |
349 /// For example if we had the ClassDeclaration node for `FontElement`: | 331 /// For example if we had the ClassDeclaration node for `FontElement`: |
350 /// | 332 /// |
351 /// @JsName('HTMLFontElement') | 333 /// @JsName('HTMLFontElement') |
352 /// @deprecated | 334 /// @deprecated |
353 /// class FontElement { ... } | 335 /// class FontElement { ... } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 } else { | 445 } else { |
464 // TODO(jmesserly): this is for backwards compat, but not sure it's very | 446 // TODO(jmesserly): this is for backwards compat, but not sure it's very |
465 // useful to log this. | 447 // useful to log this. |
466 return 'AnalyzerMessage'; | 448 return 'AnalyzerMessage'; |
467 } | 449 } |
468 } | 450 } |
469 | 451 |
470 bool isInlineJS(Element e) => e is FunctionElement && | 452 bool isInlineJS(Element e) => e is FunctionElement && |
471 e.library.source.uri.toString() == 'dart:_foreign_helper' && | 453 e.library.source.uri.toString() == 'dart:_foreign_helper' && |
472 e.name == 'JS'; | 454 e.name == 'JS'; |
OLD | NEW |