| 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; |
| 11 import 'package:analyzer/src/generated/ast.dart' | 11 import 'package:analyzer/src/generated/ast.dart' |
| 12 show | 12 show |
| 13 ImportDirective, | 13 ImportDirective, |
| 14 ExportDirective, | 14 ExportDirective, |
| 15 PartDirective, | 15 PartDirective, |
| 16 CompilationUnit, | 16 CompilationUnit, |
| 17 Identifier, | 17 Identifier, |
| 18 AnnotatedNode, | 18 AnnotatedNode, |
| 19 AstNode; | 19 AstNode; |
| 20 import 'package:analyzer/src/generated/engine.dart' | 20 import 'package:analyzer/src/generated/engine.dart' |
| 21 show ParseDartTask, AnalysisContext; | 21 show ParseDartTask, AnalysisContext; |
| 22 import 'package:analyzer/src/generated/source.dart' show Source; | 22 import 'package:analyzer/src/generated/source.dart' show Source; |
| 23 import 'package:analyzer/src/generated/element.dart'; | 23 import 'package:analyzer/src/generated/element.dart'; |
| 24 import 'package:analyzer/analyzer.dart' show parseDirectives; | 24 import 'package:analyzer/analyzer.dart' show parseDirectives; |
| 25 import 'package:crypto/crypto.dart' show CryptoUtils, MD5; | 25 import 'package:crypto/crypto.dart' show CryptoUtils, MD5; |
| 26 import 'package:source_span/source_span.dart'; | 26 import 'package:source_span/source_span.dart'; |
| 27 | 27 |
| 28 import 'js/keywords.dart'; |
| 29 |
| 28 bool isDartPrivateLibrary(LibraryElement library) { | 30 bool isDartPrivateLibrary(LibraryElement library) { |
| 29 var uri = library.source.uri; | 31 var uri = library.source.uri; |
| 30 if (uri.scheme != "dart") return false; | 32 if (uri.scheme != "dart") return false; |
| 31 return Identifier.isPrivateName(uri.path); | 33 return Identifier.isPrivateName(uri.path); |
| 32 } | 34 } |
| 33 | 35 |
| 34 /// Choose a canonical name from the library element. This is safe to use as a | 36 /// Choose a canonical name from the library element. This is safe to use as a |
| 35 /// namespace in JS and Dart code generation. This never uses the library's | 37 /// namespace in JS and Dart code generation. This never uses the library's |
| 36 /// name (the identifier in the `library` declaration) as it doesn't have any | 38 /// name (the identifier in the `library` declaration) as it doesn't have any |
| 37 /// meaningful rules enforced. | 39 /// meaningful rules enforced. |
| 38 String canonicalLibraryName(LibraryElement library) { | 40 String canonicalLibraryName(LibraryElement library) { |
| 39 var uri = library.source.uri; | 41 var uri = library.source.uri; |
| 40 return path.basenameWithoutExtension(uri.pathSegments.last); | 42 var name = path.basenameWithoutExtension(uri.pathSegments.last); |
| 43 return _toIdentifier(name); |
| 41 } | 44 } |
| 42 | 45 |
| 46 /// Escape [name] to make it into a valid identifier. |
| 47 String _toIdentifier(String name) { |
| 48 if (name.length == 0) return r'$'; |
| 49 |
| 50 // Escape any invalid characters |
| 51 StringBuffer buffer = null; |
| 52 for (int i = 0; i < name.length; i++) { |
| 53 var ch = name[i]; |
| 54 var needsEscape = ch == r'$' || _invalidCharInIdentifier.hasMatch(ch); |
| 55 if (needsEscape && buffer == null) { |
| 56 buffer = new StringBuffer(name.substring(0, i)); |
| 57 } |
| 58 if (buffer != null) { |
| 59 buffer.write(needsEscape ? '\$${ch.codeUnits.join("")}' : ch); |
| 60 } |
| 61 } |
| 62 |
| 63 var result = buffer != null ? '$buffer' : name; |
| 64 // Ensure the idenifier first character is not numeric and that the whole |
| 65 // identifier is not a keyword. |
| 66 if (result.startsWith(new RegExp('[0-9]')) || isJsKeyword(result)) { |
| 67 return '\$$result'; |
| 68 } |
| 69 return result; |
| 70 } |
| 71 |
| 72 // Invalid characters for identifiers, which would need to be escaped. |
| 73 final _invalidCharInIdentifier = new RegExp(r'[^A-Za-z_$0-9]'); |
| 74 |
| 43 /// Returns all libraries transitively imported or exported from [start]. | 75 /// Returns all libraries transitively imported or exported from [start]. |
| 44 Iterable<LibraryElement> reachableLibraries(LibraryElement start) { | 76 Iterable<LibraryElement> reachableLibraries(LibraryElement start) { |
| 45 var results = <LibraryElement>[]; | 77 var results = <LibraryElement>[]; |
| 46 var seen = new Set(); | 78 var seen = new Set(); |
| 47 void find(LibraryElement lib) { | 79 void find(LibraryElement lib) { |
| 48 if (seen.contains(lib)) return; | 80 if (seen.contains(lib)) return; |
| 49 seen.add(lib); | 81 seen.add(lib); |
| 50 results.add(lib); | 82 results.add(lib); |
| 51 lib.importedLibraries.forEach(find); | 83 lib.importedLibraries.forEach(find); |
| 52 lib.exportedLibraries.forEach(find); | 84 lib.exportedLibraries.forEach(find); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 locationForOffset(unit, uri, end), '$text'); | 292 locationForOffset(unit, uri, end), '$text'); |
| 261 } | 293 } |
| 262 | 294 |
| 263 /// Computes a hash for the given contents. | 295 /// Computes a hash for the given contents. |
| 264 String computeHash(String contents) { | 296 String computeHash(String contents) { |
| 265 if (contents == null || contents == '') return null; | 297 if (contents == null || contents == '') return null; |
| 266 return CryptoUtils.bytesToHex((new MD5()..add(contents.codeUnits)).close()); | 298 return CryptoUtils.bytesToHex((new MD5()..add(contents.codeUnits)).close()); |
| 267 } | 299 } |
| 268 | 300 |
| 269 String resourceOutputPath(Uri resourceUri) => resourceUri.path; | 301 String resourceOutputPath(Uri resourceUri) => resourceUri.path; |
| OLD | NEW |