| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library engine.sdk; | 5 library analyzer.src.generated.sdk; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'engine.dart' show AnalysisContext; | 10 import 'package:analyzer/dart/ast/visitor.dart'; |
| 11 import 'source.dart' show ContentCache, Source, UriKind; | 11 import 'package:analyzer/src/generated/engine.dart' |
| 12 show AnalysisContext, AnalysisOptions, AnalysisOptionsImpl; |
| 13 import 'package:analyzer/src/generated/source.dart' show Source; |
| 14 import 'package:analyzer/src/generated/utilities_general.dart'; |
| 15 import 'package:analyzer/src/summary/idl.dart' show PackageBundle; |
| 16 |
| 17 /** |
| 18 * A function used to create a new DartSdk with the given [options]. If the |
| 19 * passed [options] are `null`, then default options are used. |
| 20 */ |
| 21 typedef DartSdk SdkCreator(AnalysisOptions options); |
| 12 | 22 |
| 13 /** | 23 /** |
| 14 * A Dart SDK installed in a specified location. | 24 * A Dart SDK installed in a specified location. |
| 15 */ | 25 */ |
| 16 abstract class DartSdk { | 26 abstract class DartSdk { |
| 17 /** | 27 /** |
| 18 * The short name of the dart SDK 'async' library. | 28 * The short name of the dart SDK 'async' library. |
| 19 */ | 29 */ |
| 20 static final String DART_ASYNC = "dart:async"; | 30 static const String DART_ASYNC = "dart:async"; |
| 21 | 31 |
| 22 /** | 32 /** |
| 23 * The short name of the dart SDK 'core' library. | 33 * The short name of the dart SDK 'core' library. |
| 24 */ | 34 */ |
| 25 static final String DART_CORE = "dart:core"; | 35 static const String DART_CORE = "dart:core"; |
| 26 | 36 |
| 27 /** | 37 /** |
| 28 * The short name of the dart SDK 'html' library. | 38 * The short name of the dart SDK 'html' library. |
| 29 */ | 39 */ |
| 30 static final String DART_HTML = "dart:html"; | 40 static const String DART_HTML = "dart:html"; |
| 41 |
| 42 /** |
| 43 * The prefix shared by all dart library URIs. |
| 44 */ |
| 45 static const String DART_LIBRARY_PREFIX = "dart:"; |
| 31 | 46 |
| 32 /** | 47 /** |
| 33 * The version number that is returned when the real version number could not | 48 * The version number that is returned when the real version number could not |
| 34 * be determined. | 49 * be determined. |
| 35 */ | 50 */ |
| 36 static final String DEFAULT_VERSION = "0"; | 51 static const String DEFAULT_VERSION = "0"; |
| 37 | 52 |
| 38 /** | 53 /** |
| 39 * Return the analysis context used for all of the sources in this [DartSdk]. | 54 * Return the analysis context used for all of the sources in this [DartSdk]. |
| 40 */ | 55 */ |
| 41 AnalysisContext get context; | 56 AnalysisContext get context; |
| 42 | 57 |
| 43 /** | 58 /** |
| 44 * Return a list containing all of the libraries defined in this SDK. | 59 * Return a list containing all of the libraries defined in this SDK. |
| 45 */ | 60 */ |
| 46 List<SdkLibrary> get sdkLibraries; | 61 List<SdkLibrary> get sdkLibraries; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 57 */ | 72 */ |
| 58 List<String> get uris; | 73 List<String> get uris; |
| 59 | 74 |
| 60 /** | 75 /** |
| 61 * Return a source representing the given 'file:' [uri] if the file is in this | 76 * Return a source representing the given 'file:' [uri] if the file is in this |
| 62 * SDK, or `null` if the file is not in this SDK. | 77 * SDK, or `null` if the file is not in this SDK. |
| 63 */ | 78 */ |
| 64 Source fromFileUri(Uri uri); | 79 Source fromFileUri(Uri uri); |
| 65 | 80 |
| 66 /** | 81 /** |
| 82 * Return the linked [PackageBundle] for this SDK, if it can be provided, or |
| 83 * `null` otherwise. |
| 84 * |
| 85 * This is a temporary API, don't use it. |
| 86 */ |
| 87 PackageBundle getLinkedBundle(); |
| 88 |
| 89 /** |
| 67 * Return the library representing the library with the given 'dart:' [uri], | 90 * Return the library representing the library with the given 'dart:' [uri], |
| 68 * or `null` if the given URI does not denote a library in this SDK. | 91 * or `null` if the given URI does not denote a library in this SDK. |
| 69 */ | 92 */ |
| 70 SdkLibrary getSdkLibrary(String uri); | 93 SdkLibrary getSdkLibrary(String uri); |
| 71 | 94 |
| 72 /** | 95 /** |
| 73 * Return the source representing the library with the given 'dart:' [uri], or | 96 * Return the source representing the library with the given 'dart:' [uri], or |
| 74 * `null` if the given URI does not denote a library in this SDK. | 97 * `null` if the given URI does not denote a library in this SDK. |
| 75 */ | 98 */ |
| 76 Source mapDartUri(String uri); | 99 Source mapDartUri(String uri); |
| 77 } | 100 } |
| 78 | 101 |
| 79 /** | 102 /** |
| 103 * Manages the DartSdk's that have been created. Clients need to create multiple |
| 104 * SDKs when the analysis options associated with those SDK's contexts will |
| 105 * produce different analysis results. |
| 106 */ |
| 107 class DartSdkManager { |
| 108 /** |
| 109 * The absolute path to the directory containing the default SDK. |
| 110 */ |
| 111 final String defaultSdkDirectory; |
| 112 |
| 113 /** |
| 114 * A flag indicating whether it is acceptable to use summaries when they are |
| 115 * available. |
| 116 */ |
| 117 final bool canUseSummaries; |
| 118 |
| 119 /** |
| 120 * The function used to create new SDK's. |
| 121 */ |
| 122 final SdkCreator sdkCreator; |
| 123 |
| 124 /** |
| 125 * A table mapping (an encoding of) analysis options and SDK locations to the |
| 126 * DartSdk from that location that has been configured with those options. |
| 127 */ |
| 128 Map<SdkDescription, DartSdk> sdkMap = new HashMap<SdkDescription, DartSdk>(); |
| 129 |
| 130 /** |
| 131 * Initialize a newly created manager. |
| 132 */ |
| 133 DartSdkManager( |
| 134 this.defaultSdkDirectory, this.canUseSummaries, this.sdkCreator); |
| 135 |
| 136 /** |
| 137 * Return any SDK that has been created, or `null` if no SDKs have been |
| 138 * created. |
| 139 */ |
| 140 DartSdk get anySdk { |
| 141 if (sdkMap.isEmpty) { |
| 142 return null; |
| 143 } |
| 144 return sdkMap.values.first; |
| 145 } |
| 146 |
| 147 /** |
| 148 * Return a list of the descriptors of the SDKs that are currently being |
| 149 * managed. |
| 150 */ |
| 151 List<SdkDescription> get sdkDescriptors => sdkMap.keys.toList(); |
| 152 |
| 153 /** |
| 154 * Return the Dart SDK that is appropriate for the given analysis [options]. |
| 155 * If such an SDK has not yet been created, then the [sdkCreator] will be |
| 156 * invoked to create it. |
| 157 */ |
| 158 DartSdk getSdk(SdkDescription description, DartSdk ifAbsent()) { |
| 159 return sdkMap.putIfAbsent(description, ifAbsent); |
| 160 } |
| 161 |
| 162 /** |
| 163 * Return the Dart SDK that is appropriate for the given analysis [options]. |
| 164 * If such an SDK has not yet been created, then the [sdkCreator] will be |
| 165 * invoked to create it. |
| 166 */ |
| 167 DartSdk getSdkForOptions(AnalysisOptions options) { |
| 168 // TODO(brianwilkerson) Remove this method and the field sdkCreator. |
| 169 SdkDescription description = |
| 170 new SdkDescription(<String>[defaultSdkDirectory], options); |
| 171 return getSdk(description, () => sdkCreator(options)); |
| 172 } |
| 173 } |
| 174 |
| 175 /** |
| 80 * A map from Dart library URI's to the [SdkLibraryImpl] representing that | 176 * A map from Dart library URI's to the [SdkLibraryImpl] representing that |
| 81 * library. | 177 * library. |
| 82 */ | 178 */ |
| 83 class LibraryMap { | 179 class LibraryMap { |
| 84 /** | 180 /** |
| 85 * A table mapping Dart library URI's to the library. | 181 * A table mapping Dart library URI's to the library. |
| 86 */ | 182 */ |
| 87 HashMap<String, SdkLibraryImpl> _libraryMap = | 183 LinkedHashMap<String, SdkLibraryImpl> _libraryMap = |
| 88 new HashMap<String, SdkLibraryImpl>(); | 184 new LinkedHashMap<String, SdkLibraryImpl>(); |
| 89 | 185 |
| 90 /** | 186 /** |
| 91 * Return a list containing all of the sdk libraries in this mapping. | 187 * Return a list containing all of the sdk libraries in this mapping. |
| 92 */ | 188 */ |
| 93 List<SdkLibrary> get sdkLibraries => new List.from(_libraryMap.values); | 189 List<SdkLibrary> get sdkLibraries => new List.from(_libraryMap.values); |
| 94 | 190 |
| 95 /** | 191 /** |
| 96 * Return a list containing the library URI's for which a mapping is available
. | 192 * Return a list containing the library URI's for which a mapping is available
. |
| 97 */ | 193 */ |
| 98 List<String> get uris => new List.from(_libraryMap.keys.toSet()); | 194 List<String> get uris => _libraryMap.keys.toList(); |
| 99 | 195 |
| 100 /** | 196 /** |
| 101 * Return the library with the given 'dart:' [uri], or `null` if the URI does | 197 * Return the library with the given 'dart:' [uri], or `null` if the URI does |
| 102 * not map to a library. | 198 * not map to a library. |
| 103 */ | 199 */ |
| 104 SdkLibrary getLibrary(String uri) => _libraryMap[uri]; | 200 SdkLibrary getLibrary(String uri) => _libraryMap[uri]; |
| 105 | 201 |
| 106 /** | 202 /** |
| 107 * Set the library with the given 'dart:' [uri] to the given [library]. | 203 * Set the library with the given 'dart:' [uri] to the given [library]. |
| 108 */ | 204 */ |
| 109 void setLibrary(String dartUri, SdkLibraryImpl library) { | 205 void setLibrary(String dartUri, SdkLibraryImpl library) { |
| 110 _libraryMap[dartUri] = library; | 206 _libraryMap[dartUri] = library; |
| 111 } | 207 } |
| 112 | 208 |
| 113 /** | 209 /** |
| 114 * Return the number of library URI's for which a mapping is available. | 210 * Return the number of library URI's for which a mapping is available. |
| 115 */ | 211 */ |
| 116 int size() => _libraryMap.length; | 212 int size() => _libraryMap.length; |
| 117 } | 213 } |
| 118 | 214 |
| 215 /** |
| 216 * A description of a [DartSdk]. |
| 217 */ |
| 218 class SdkDescription { |
| 219 /** |
| 220 * The paths to the files or directories that define the SDK. |
| 221 */ |
| 222 final List<String> paths; |
| 223 |
| 224 /** |
| 225 * The analysis options that will be used by the SDK's context. |
| 226 */ |
| 227 final AnalysisOptions options; |
| 228 |
| 229 /** |
| 230 * Initialize a newly created SDK description to describe an SDK based on the |
| 231 * files or directories at the given [paths] that is analyzed using the given |
| 232 * [options]. |
| 233 */ |
| 234 SdkDescription(this.paths, this.options); |
| 235 |
| 236 @override |
| 237 int get hashCode { |
| 238 int hashCode = options.encodeCrossContextOptions(); |
| 239 for (String path in paths) { |
| 240 hashCode = JenkinsSmiHash.combine(hashCode, path.hashCode); |
| 241 } |
| 242 return JenkinsSmiHash.finish(hashCode); |
| 243 } |
| 244 |
| 245 @override |
| 246 bool operator ==(Object other) { |
| 247 if (other is SdkDescription) { |
| 248 if (options.encodeCrossContextOptions() != |
| 249 other.options.encodeCrossContextOptions()) { |
| 250 return false; |
| 251 } |
| 252 int length = paths.length; |
| 253 if (other.paths.length != length) { |
| 254 return false; |
| 255 } |
| 256 for (int i = 0; i < length; i++) { |
| 257 if (other.paths[i] != paths[i]) { |
| 258 return false; |
| 259 } |
| 260 } |
| 261 return true; |
| 262 } |
| 263 return false; |
| 264 } |
| 265 |
| 266 @override |
| 267 String toString() { |
| 268 StringBuffer buffer = new StringBuffer(); |
| 269 bool needsSeparator = false; |
| 270 void add(String optionName) { |
| 271 if (needsSeparator) { |
| 272 buffer.write(', '); |
| 273 } |
| 274 buffer.write(optionName); |
| 275 needsSeparator = true; |
| 276 } |
| 277 for (String path in paths) { |
| 278 add(path); |
| 279 } |
| 280 if (needsSeparator) { |
| 281 buffer.write(' '); |
| 282 } |
| 283 buffer.write('('); |
| 284 buffer.write(AnalysisOptionsImpl |
| 285 .decodeCrossContextOptions(options.encodeCrossContextOptions())); |
| 286 buffer.write(')'); |
| 287 return buffer.toString(); |
| 288 } |
| 289 } |
| 290 |
| 119 class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<Object> { | 291 class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<Object> { |
| 120 /** | 292 /** |
| 121 * The prefix added to the name of a library to form the URI used in code to | 293 * The prefix added to the name of a library to form the URI used in code to |
| 122 * reference the library. | 294 * reference the library. |
| 123 */ | 295 */ |
| 124 static String _LIBRARY_PREFIX = "dart:"; | 296 static String _LIBRARY_PREFIX = "dart:"; |
| 125 | 297 |
| 126 /** | 298 /** |
| 127 * The name of the optional parameter used to indicate whether the library is | 299 * The name of the optional parameter used to indicate whether the library is |
| 128 * an implementation library. | 300 * an implementation library. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 * [_useDart2jsPaths] is `true`. | 348 * [_useDart2jsPaths] is `true`. |
| 177 */ | 349 */ |
| 178 SdkLibrariesReader_LibraryBuilder(this._useDart2jsPaths); | 350 SdkLibrariesReader_LibraryBuilder(this._useDart2jsPaths); |
| 179 | 351 |
| 180 /** | 352 /** |
| 181 * Return the library map that was populated by visiting the AST structure | 353 * Return the library map that was populated by visiting the AST structure |
| 182 * parsed from the contents of the libraries file. | 354 * parsed from the contents of the libraries file. |
| 183 */ | 355 */ |
| 184 LibraryMap get librariesMap => _librariesMap; | 356 LibraryMap get librariesMap => _librariesMap; |
| 185 | 357 |
| 186 | |
| 187 // To be backwards-compatible the new categories field is translated to | 358 // To be backwards-compatible the new categories field is translated to |
| 188 // an old approximation. | 359 // an old approximation. |
| 189 String convertCategories(String categories) { | 360 String convertCategories(String categories) { |
| 190 switch (categories) { | 361 switch (categories) { |
| 191 case "": return "Internal"; | 362 case "": |
| 192 case "Client": return "Client"; | 363 return "Internal"; |
| 193 case "Server": return "Server"; | 364 case "Client": |
| 194 case "Client,Server": return "Shared"; | 365 return "Client"; |
| 195 case "Client,Server,Embedded": return "Shared"; | 366 case "Server": |
| 367 return "Server"; |
| 368 case "Client,Server": |
| 369 return "Shared"; |
| 370 case "Client,Server,Embedded": |
| 371 return "Shared"; |
| 196 } | 372 } |
| 197 return "Shared"; | 373 return "Shared"; |
| 198 } | 374 } |
| 199 | 375 |
| 200 @override | 376 @override |
| 201 Object visitMapLiteralEntry(MapLiteralEntry node) { | 377 Object visitMapLiteralEntry(MapLiteralEntry node) { |
| 202 String libraryName = null; | 378 String libraryName = null; |
| 203 Expression key = node.key; | 379 Expression key = node.key; |
| 204 if (key is SimpleStringLiteral) { | 380 if (key is SimpleStringLiteral) { |
| 205 libraryName = "$_LIBRARY_PREFIX${key.value}"; | 381 libraryName = "$_LIBRARY_PREFIX${key.value}"; |
| 206 } | 382 } |
| 207 Expression value = node.value; | 383 Expression value = node.value; |
| 208 if (value is InstanceCreationExpression) { | 384 if (value is InstanceCreationExpression) { |
| 209 SdkLibraryImpl library = new SdkLibraryImpl(libraryName); | 385 SdkLibraryImpl library = new SdkLibraryImpl(libraryName); |
| 210 List<Expression> arguments = value.argumentList.arguments; | 386 List<Expression> arguments = value.argumentList.arguments; |
| 211 for (Expression argument in arguments) { | 387 for (Expression argument in arguments) { |
| 212 if (argument is SimpleStringLiteral) { | 388 if (argument is SimpleStringLiteral) { |
| 213 library.path = argument.value; | 389 library.path = argument.value; |
| 214 } else if (argument is NamedExpression) { | 390 } else if (argument is NamedExpression) { |
| 215 String name = argument.name.label.name; | 391 String name = argument.name.label.name; |
| 216 Expression expression = argument.expression; | 392 Expression expression = argument.expression; |
| 217 if (name == _CATEGORIES) { | 393 if (name == _CATEGORIES) { |
| 218 library.category = | 394 library.category = |
| 219 convertCategories((expression as StringLiteral).stringValue); | 395 convertCategories((expression as StringLiteral).stringValue); |
| 220 } else if (name == _IMPLEMENTATION) { | 396 } else if (name == _IMPLEMENTATION) { |
| 221 library.implementation = (expression as BooleanLiteral).value; | 397 library._implementation = (expression as BooleanLiteral).value; |
| 222 } else if (name == _DOCUMENTED) { | 398 } else if (name == _DOCUMENTED) { |
| 223 library.documented = (expression as BooleanLiteral).value; | 399 library.documented = (expression as BooleanLiteral).value; |
| 224 } else if (name == _PLATFORMS) { | 400 } else if (name == _PLATFORMS) { |
| 225 if (expression is SimpleIdentifier) { | 401 if (expression is SimpleIdentifier) { |
| 226 String identifier = expression.name; | 402 String identifier = expression.name; |
| 227 if (identifier == _VM_PLATFORM) { | 403 if (identifier == _VM_PLATFORM) { |
| 228 library.setVmLibrary(); | 404 library.setVmLibrary(); |
| 229 } else { | 405 } else { |
| 230 library.setDart2JsLibrary(); | 406 library.setDart2JsLibrary(); |
| 231 } | 407 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 * whether a library is intended to work on the dart2js platform. | 480 * whether a library is intended to work on the dart2js platform. |
| 305 */ | 481 */ |
| 306 static int DART2JS_PLATFORM = 1; | 482 static int DART2JS_PLATFORM = 1; |
| 307 | 483 |
| 308 /** | 484 /** |
| 309 * The bit mask used to access the bit representing the flag indicating | 485 * The bit mask used to access the bit representing the flag indicating |
| 310 * whether a library is intended to work on the VM platform. | 486 * whether a library is intended to work on the VM platform. |
| 311 */ | 487 */ |
| 312 static int VM_PLATFORM = 2; | 488 static int VM_PLATFORM = 2; |
| 313 | 489 |
| 314 /** | 490 @override |
| 315 * The short name of the library. This is the name used after 'dart:' in a | |
| 316 * URI. | |
| 317 */ | |
| 318 final String shortName; | 491 final String shortName; |
| 319 | 492 |
| 320 /** | 493 /** |
| 321 * The path to the file defining the library. The path is relative to the | 494 * The path to the file defining the library. The path is relative to the |
| 322 * 'lib' directory within the SDK. | 495 * 'lib' directory within the SDK. |
| 323 */ | 496 */ |
| 497 @override |
| 324 String path = null; | 498 String path = null; |
| 325 | 499 |
| 326 /** | 500 /** |
| 327 * The name of the category containing the library. Unless otherwise specified | 501 * The name of the category containing the library. Unless otherwise specified |
| 328 * in the libraries file all libraries are assumed to be shared between server | 502 * in the libraries file all libraries are assumed to be shared between server |
| 329 * and client. | 503 * and client. |
| 330 */ | 504 */ |
| 505 @override |
| 331 String category = "Shared"; | 506 String category = "Shared"; |
| 332 | 507 |
| 333 /** | 508 /** |
| 334 * A flag indicating whether the library is documented. | 509 * A flag indicating whether the library is documented. |
| 335 */ | 510 */ |
| 336 bool _documented = true; | 511 bool _documented = true; |
| 337 | 512 |
| 338 /** | 513 /** |
| 339 * A flag indicating whether the library is an implementation library. | 514 * A flag indicating whether the library is an implementation library. |
| 340 */ | 515 */ |
| (...skipping 10 matching lines...) Expand all Loading... |
| 351 */ | 526 */ |
| 352 SdkLibraryImpl(this.shortName); | 527 SdkLibraryImpl(this.shortName); |
| 353 | 528 |
| 354 /** | 529 /** |
| 355 * Set whether the library is documented. | 530 * Set whether the library is documented. |
| 356 */ | 531 */ |
| 357 void set documented(bool documented) { | 532 void set documented(bool documented) { |
| 358 this._documented = documented; | 533 this._documented = documented; |
| 359 } | 534 } |
| 360 | 535 |
| 361 /** | |
| 362 * Set whether the library is an implementation library. | |
| 363 */ | |
| 364 void set implementation(bool implementation) { | |
| 365 this._implementation = implementation; | |
| 366 } | |
| 367 | |
| 368 @override | 536 @override |
| 369 bool get isDart2JsLibrary => (_platforms & DART2JS_PLATFORM) != 0; | 537 bool get isDart2JsLibrary => (_platforms & DART2JS_PLATFORM) != 0; |
| 370 | 538 |
| 371 @override | 539 @override |
| 372 bool get isDocumented => _documented; | 540 bool get isDocumented => _documented; |
| 373 | 541 |
| 374 @override | 542 @override |
| 375 bool get isImplementation => _implementation; | 543 bool get isImplementation => _implementation; |
| 376 | 544 |
| 377 @override | 545 @override |
| 378 bool get isInternal => "Internal" == category; | 546 bool get isInternal => category == "Internal"; |
| 379 | 547 |
| 380 @override | 548 @override |
| 381 bool get isShared => category == "Shared"; | 549 bool get isShared => category == "Shared"; |
| 382 | 550 |
| 383 @override | 551 @override |
| 384 bool get isVmLibrary => (_platforms & VM_PLATFORM) != 0; | 552 bool get isVmLibrary => (_platforms & VM_PLATFORM) != 0; |
| 385 | 553 |
| 386 /** | 554 /** |
| 387 * Record that this library can be compiled to JavaScript by dart2js. | 555 * Record that this library can be compiled to JavaScript by dart2js. |
| 388 */ | 556 */ |
| 389 void setDart2JsLibrary() { | 557 void setDart2JsLibrary() { |
| 390 _platforms |= DART2JS_PLATFORM; | 558 _platforms |= DART2JS_PLATFORM; |
| 391 } | 559 } |
| 392 | 560 |
| 393 /** | 561 /** |
| 394 * Record that this library can be run on the VM. | 562 * Record that this library can be run on the VM. |
| 395 */ | 563 */ |
| 396 void setVmLibrary() { | 564 void setVmLibrary() { |
| 397 _platforms |= VM_PLATFORM; | 565 _platforms |= VM_PLATFORM; |
| 398 } | 566 } |
| 399 } | 567 } |
| OLD | NEW |