OLD | NEW |
---|---|
1 // (c) 2015, the Dart Team. All rights reserved. Use of this | 1 // (c) 2015, the Dart Team. All rights reserved. Use of this |
2 // source code is governed by a BSD-style license that can be found in | 2 // source code is governed by a BSD-style license that can be found in |
3 // the LICENSE file. | 3 // the LICENSE file. |
4 | 4 |
5 library reflectable.src.transformer_implementation; | 5 library reflectable.src.transformer_implementation; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:convert'; | 8 import 'dart:convert'; |
9 import 'dart:developer' as developer; | 9 import 'dart:developer' as developer; |
10 import 'dart:io'; | 10 import 'dart:io'; |
11 import 'package:analyzer/src/generated/ast.dart'; | 11 import 'package:analyzer/src/generated/ast.dart'; |
12 import 'package:analyzer/src/generated/constant.dart'; | 12 import 'package:analyzer/src/generated/constant.dart'; |
13 import 'package:analyzer/src/generated/element.dart'; | 13 import 'package:analyzer/src/generated/element.dart'; |
14 import 'package:analyzer/src/generated/utilities_dart.dart'; | 14 import 'package:analyzer/src/generated/utilities_dart.dart'; |
15 import 'package:barback/barback.dart'; | 15 import 'package:barback/barback.dart'; |
16 import 'package:code_transformers/resolver.dart'; | 16 import 'package:code_transformers/resolver.dart'; |
17 import 'package:dart_style/dart_style.dart'; | 17 import 'package:dart_style/dart_style.dart'; |
18 import 'package:path/path.dart' as path; | 18 import 'package:path/path.dart' as path; |
19 import 'element_capability.dart' as ec; | 19 import 'element_capability.dart' as ec; |
20 import 'encoding_constants.dart' as constants; | 20 import 'encoding_constants.dart' as constants; |
21 import 'fixed_point.dart'; | 21 import 'fixed_point.dart'; |
22 import 'reflectable_class_constants.dart' as reflectable_class_constants; | 22 import 'reflectable_class_constants.dart' as reflectable_class_constants; |
23 import 'transformer_errors.dart' as errors; | 23 import 'transformer_errors.dart' as errors; |
24 | 24 |
25 /// Specifiers for warnings that may be suppressed; `allWarnings` disables all | |
26 /// warnings, and the remaining values are concerned with individual warnings. | |
27 /// Remember to update the explanatory text in [_findSuppressWarnings] whenever | |
28 /// this list is updated. | |
29 enum WarningKind { | |
30 allWarnings, | |
sigurdm
2015/11/17 14:05:21
allWarnings is not really a kind of warning.
Why
eernst
2015/11/17 14:38:13
Did think about that, and it is indeed a more regu
| |
31 missingEntryPoint, | |
32 badSuperclass, | |
33 badNamePattern, | |
34 badMetadata | |
35 } | |
36 | |
25 // Single source of instances of [Resolver], shared across multiple | 37 // Single source of instances of [Resolver], shared across multiple |
26 // invocations of `apply` to save memory. | 38 // invocations of `apply` to save memory. |
27 Resolvers _resolvers = new Resolvers(dartSdkDirectory); | 39 Resolvers _resolvers = new Resolvers(dartSdkDirectory); |
28 | 40 |
29 class ReflectionWorld { | 41 class ReflectionWorld { |
30 final Resolver resolver; | 42 final Resolver resolver; |
31 final AssetId generatedLibraryId; | 43 final AssetId generatedLibraryId; |
32 final List<_ReflectorDomain> reflectors; | 44 final List<_ReflectorDomain> reflectors; |
33 final LibraryElement reflectableLibrary; | 45 final LibraryElement reflectableLibrary; |
34 final LibraryElement entryPointLibrary; | 46 final LibraryElement entryPointLibrary; |
(...skipping 2215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2250 // because we will then simply work on a normal Dart program that uses | 2262 // because we will then simply work on a normal Dart program that uses |
2251 // dart:mirrors, which should have the same behavior as the translated | 2263 // dart:mirrors, which should have the same behavior as the translated |
2252 // program, and this could work quite well in practice, except for | 2264 // program, and this could work quite well in practice, except for |
2253 // debugging which is concerned with the generated code (but that would | 2265 // debugging which is concerned with the generated code (but that would |
2254 // ideally be an infrequent occurrence). | 2266 // ideally be an infrequent occurrence). |
2255 | 2267 |
2256 class TransformerImplementation { | 2268 class TransformerImplementation { |
2257 TransformLogger _logger; | 2269 TransformLogger _logger; |
2258 Resolver _resolver; | 2270 Resolver _resolver; |
2259 bool _formatted; | 2271 bool _formatted; |
2272 List<WarningKind> _suppressedWarnings; | |
2273 | |
2274 bool _warningEnabled(WarningKind kind) { | |
2275 if (_suppressedWarnings.contains(WarningKind.allWarnings)) return false; | |
2276 return !_suppressedWarnings.contains(kind); | |
2277 } | |
2260 | 2278 |
2261 /// Checks whether the given [type] from the target program is "our" | 2279 /// Checks whether the given [type] from the target program is "our" |
2262 /// class [Reflectable] by looking up the static field | 2280 /// class [Reflectable] by looking up the static field |
2263 /// [Reflectable.thisClassId] and checking its value (which is a 40 | 2281 /// [Reflectable.thisClassId] and checking its value (which is a 40 |
2264 /// character string computed by sha1sum on an old version of | 2282 /// character string computed by sha1sum on an old version of |
2265 /// reflectable.dart). | 2283 /// reflectable.dart). |
2266 /// | 2284 /// |
2267 /// Discussion of approach: Checking that we have found the correct | 2285 /// Discussion of approach: Checking that we have found the correct |
2268 /// [Reflectable] class is crucial for correctness, and the "obvious" | 2286 /// [Reflectable] class is crucial for correctness, and the "obvious" |
2269 /// approach of just looking up the library and then the class with the | 2287 /// approach of just looking up the library and then the class with the |
(...skipping 14 matching lines...) Expand all Loading... | |
2284 if (idField is ConstFieldElementImpl) { | 2302 if (idField is ConstFieldElementImpl) { |
2285 EvaluationResultImpl idResult = idField.evaluationResult; | 2303 EvaluationResultImpl idResult = idField.evaluationResult; |
2286 if (idResult != null) { | 2304 if (idResult != null) { |
2287 return idField.constantValue.toStringValue() == | 2305 return idField.constantValue.toStringValue() == |
2288 reflectable_class_constants.id; | 2306 reflectable_class_constants.id; |
2289 } | 2307 } |
2290 // idResult == null: analyzer/.../element.dart does not specify | 2308 // idResult == null: analyzer/.../element.dart does not specify |
2291 // whether this could happen, but it is surely not the right | 2309 // whether this could happen, but it is surely not the right |
2292 // class, so we fall through. | 2310 // class, so we fall through. |
2293 } | 2311 } |
2294 // Not a const field, cannot be the right class. | 2312 // Not a const field, or failed the test, cannot be the right class. |
2295 return false; | 2313 return false; |
2296 } | 2314 } |
2297 | 2315 |
2298 /// Returns the ClassElement in the target program which corresponds to class | 2316 /// Returns the ClassElement in the target program which corresponds to class |
2299 /// [Reflectable]. | 2317 /// [Reflectable]. |
2300 ClassElement _findReflectableClassElement(LibraryElement reflectableLibrary) { | 2318 ClassElement _findReflectableClassElement(LibraryElement reflectableLibrary) { |
2301 for (CompilationUnitElement unit in reflectableLibrary.units) { | 2319 for (CompilationUnitElement unit in reflectableLibrary.units) { |
2302 for (ClassElement type in unit.types) { | 2320 for (ClassElement type in unit.types) { |
2303 if (type.name == reflectable_class_constants.name && | 2321 if (type.name == reflectable_class_constants.name && |
2304 _equalsClassReflectable(type)) { | 2322 _equalsClassReflectable(type)) { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2395 // have no effect; it might be better to emit a diagnostic message (a | 2413 // have no effect; it might be better to emit a diagnostic message (a |
2396 // hint?) in order to notify the programmer that "it does not work". | 2414 // hint?) in order to notify the programmer that "it does not work". |
2397 // The trade-off is that such constructs may have been written by | 2415 // The trade-off is that such constructs may have been written by |
2398 // programmers who are doing something else, intentionally. To emit a | 2416 // programmers who are doing something else, intentionally. To emit a |
2399 // diagnostic message, we must check whether there is a Reflectable | 2417 // diagnostic message, we must check whether there is a Reflectable |
2400 // somewhere inside this syntactic construct, and then emit the message | 2418 // somewhere inside this syntactic construct, and then emit the message |
2401 // in cases that we "consider likely to be misunderstood". | 2419 // in cases that we "consider likely to be misunderstood". |
2402 return null; | 2420 return null; |
2403 } | 2421 } |
2404 | 2422 |
2405 _warn(String message, Element element) { | 2423 _warn(WarningKind kind, String message, [Element element]) { |
2406 _logger.warning(message, | 2424 if (_warningEnabled(kind)) { |
2407 asset: _resolver.getSourceAssetId(element), | 2425 if (element != null) { |
2408 span: _resolver.getSourceSpan(element)); | 2426 _logger.warning(message, |
2427 asset: _resolver.getSourceAssetId(element), | |
2428 span: _resolver.getSourceSpan(element)); | |
2429 } else { | |
2430 _logger.warning(message); | |
2431 } | |
2432 } | |
2409 } | 2433 } |
2410 | 2434 |
2411 /// Finds all GlobalQuantifyCapability and GlobalQuantifyMetaCapability | 2435 /// Finds all GlobalQuantifyCapability and GlobalQuantifyMetaCapability |
2412 /// annotations on imports of [reflectableLibrary], and record the arguments | 2436 /// annotations on imports of [reflectableLibrary], and record the arguments |
2413 /// of these annotations by modifying [globalPatterns] and [globalMetadata]. | 2437 /// of these annotations by modifying [globalPatterns] and [globalMetadata]. |
2414 void _findGlobalQuantifyAnnotations( | 2438 void _findGlobalQuantifyAnnotations( |
2415 Map<RegExp, List<ClassElement>> globalPatterns, | 2439 Map<RegExp, List<ClassElement>> globalPatterns, |
2416 Map<ClassElement, List<ClassElement>> globalMetadata) { | 2440 Map<ClassElement, List<ClassElement>> globalMetadata) { |
2417 LibraryElement reflectableLibrary = | 2441 LibraryElement reflectableLibrary = |
2418 _resolver.getLibraryByName("reflectable.reflectable"); | 2442 _resolver.getLibraryByName("reflectable.reflectable"); |
(...skipping 15 matching lines...) Expand all Loading... | |
2434 for (ImportElement import in library.imports) { | 2458 for (ImportElement import in library.imports) { |
2435 for (ElementAnnotationImpl metadatum in import.metadata) { | 2459 for (ElementAnnotationImpl metadatum in import.metadata) { |
2436 if (metadatum.element == globalQuantifyCapabilityConstructor) { | 2460 if (metadatum.element == globalQuantifyCapabilityConstructor) { |
2437 EvaluationResultImpl evaluation = metadatum.evaluationResult; | 2461 EvaluationResultImpl evaluation = metadatum.evaluationResult; |
2438 if (evaluation != null && evaluation.value != null) { | 2462 if (evaluation != null && evaluation.value != null) { |
2439 DartObjectImpl value = evaluation.value; | 2463 DartObjectImpl value = evaluation.value; |
2440 String pattern = value.fields["classNamePattern"].toStringValue(); | 2464 String pattern = value.fields["classNamePattern"].toStringValue(); |
2441 if (pattern == null) { | 2465 if (pattern == null) { |
2442 // TODO(sigurdm) implement: Create a span for the annotation | 2466 // TODO(sigurdm) implement: Create a span for the annotation |
2443 // rather than the import. | 2467 // rather than the import. |
2444 _warn("The classNamePattern must be a string", import); | 2468 _warn(WarningKind.badNamePattern, |
2469 "The classNamePattern must be a string", import); | |
2445 continue; | 2470 continue; |
2446 } | 2471 } |
2447 ClassElement reflector = | 2472 ClassElement reflector = |
2448 value.fields["(super)"].fields["reflector"].type.element; | 2473 value.fields["(super)"].fields["reflector"].type.element; |
2449 if (reflector == null || | 2474 if (reflector == null || |
2450 reflector.type.element.supertype.element != | 2475 reflector.type.element.supertype.element != |
2451 reflectableClass) { | 2476 reflectableClass) { |
2452 String found = | 2477 String found = |
2453 reflector == null ? "" : " Found ${reflector.name}"; | 2478 reflector == null ? "" : " Found ${reflector.name}"; |
2454 _warn( | 2479 _warn( |
2480 WarningKind.badSuperclass, | |
2455 "The reflector must be a direct subclass of Reflectable." + | 2481 "The reflector must be a direct subclass of Reflectable." + |
2456 found, | 2482 found, |
2457 import); | 2483 import); |
2458 continue; | 2484 continue; |
2459 } | 2485 } |
2460 globalPatterns | 2486 globalPatterns |
2461 .putIfAbsent(new RegExp(pattern), () => <ClassElement>[]) | 2487 .putIfAbsent(new RegExp(pattern), () => <ClassElement>[]) |
2462 .add(reflector); | 2488 .add(reflector); |
2463 } | 2489 } |
2464 } else if (metadatum.element == | 2490 } else if (metadatum.element == |
2465 globalQuantifyMetaCapabilityConstructor) { | 2491 globalQuantifyMetaCapabilityConstructor) { |
2466 EvaluationResultImpl evaluation = metadatum.evaluationResult; | 2492 EvaluationResultImpl evaluation = metadatum.evaluationResult; |
2467 if (evaluation?.value != null) { | 2493 if (evaluation?.value != null) { |
2468 DartObjectImpl value = evaluation.value; | 2494 DartObjectImpl value = evaluation.value; |
2469 Object metadataFieldValue = | 2495 Object metadataFieldValue = |
2470 value.fields["metadataType"].toTypeValue().element; | 2496 value.fields["metadataType"].toTypeValue().element; |
2471 if (metadataFieldValue == null || | 2497 if (metadataFieldValue == null || |
2472 value.fields["metadataType"].type.element != typeClass) { | 2498 value.fields["metadataType"].type.element != typeClass) { |
2473 // TODO(sigurdm) implement: Create a span for the annotation. | 2499 // TODO(sigurdm) implement: Create a span for the annotation. |
2474 _warn( | 2500 _warn( |
2501 WarningKind.badMetadata, | |
2475 "The metadata must be a Type. " | 2502 "The metadata must be a Type. " |
2476 "Found ${value.fields["metadataType"].type.element.name}", | 2503 "Found ${value.fields["metadataType"].type.element.name}", |
2477 import); | 2504 import); |
2478 continue; | 2505 continue; |
2479 } | 2506 } |
2480 ClassElement reflector = | 2507 ClassElement reflector = |
2481 value.fields["(super)"].fields["reflector"].type.element; | 2508 value.fields["(super)"].fields["reflector"].type.element; |
2482 if (reflector == null || | 2509 if (reflector == null || |
2483 reflector.type.element.supertype.element != | 2510 reflector.type.element.supertype.element != |
2484 reflectableClass) { | 2511 reflectableClass) { |
2485 String found = | 2512 String found = |
2486 reflector == null ? "" : " Found ${reflector.name}"; | 2513 reflector == null ? "" : " Found ${reflector.name}"; |
2487 _warn( | 2514 _warn( |
2515 WarningKind.badSuperclass, | |
2488 "The reflector must be a direct subclass of Reflectable." + | 2516 "The reflector must be a direct subclass of Reflectable." + |
2489 found, | 2517 found, |
2490 import); | 2518 import); |
2491 continue; | 2519 continue; |
2492 } | 2520 } |
2493 globalMetadata | 2521 globalMetadata |
2494 .putIfAbsent(metadataFieldValue, () => <ClassElement>[]) | 2522 .putIfAbsent(metadataFieldValue, () => <ClassElement>[]) |
2495 .add(reflector); | 2523 .add(reflector); |
2496 } | 2524 } |
2497 } | 2525 } |
2498 } | 2526 } |
2499 } | 2527 } |
2500 } | 2528 } |
2501 } | 2529 } |
2502 | 2530 |
2503 /// Returns a [ReflectionWorld] instantiated with all the reflectors seen by | 2531 /// Returns a [ReflectionWorld] instantiated with all the reflectors seen by |
2504 /// [_resolver] and all classes annotated by them. The [reflectableLibrary] | 2532 /// [_resolver] and all classes annotated by them. The [reflectableLibrary] |
2505 /// must be the element representing 'package:reflectable/reflectable.dart', | 2533 /// must be the element representing 'package:reflectable/reflectable.dart', |
2506 /// the [entryPoint] must be the element representing the entry point under | 2534 /// the [entryPoint] must be the element representing the entry point under |
2507 /// transformation, and [dataId] must represent the entry point as well, | 2535 /// transformation, and [dataId] must represent the entry point as well, |
2508 /// and it is used to decide whether it is possible to import other libraries | 2536 /// and it is used to decide whether it is possible to import other libraries |
2509 /// from the entry point. If the transformation is guaranteed to have no | 2537 /// from the entry point. If the transformation is guaranteed to have no |
2510 /// effect the return value is [null]. | 2538 /// effect the return value is [null]. |
2511 ReflectionWorld _computeWorld(LibraryElement reflectableLibrary, | 2539 ReflectionWorld _computeWorld(LibraryElement reflectableLibrary, |
2512 LibraryElement entryPoint, AssetId dataId) { | 2540 LibraryElement entryPoint, AssetId dataId) { |
2513 final ClassElement classReflectable = | 2541 final ClassElement classReflectable = |
2514 _findReflectableClassElement(reflectableLibrary); | 2542 _findReflectableClassElement(reflectableLibrary); |
2515 // If class `Reflectable` is absent the transformation must be a no-op. | 2543 // If class `Reflectable` is absent the transformation must be a no-op. |
2516 if (classReflectable == null) return null; | 2544 if (classReflectable == null) { |
2545 _logger.info("Ignoring entry point $entryPoint that does not " | |
2546 "include the class `Reflectable`."); | |
2547 return null; | |
2548 } | |
2517 | 2549 |
2518 // The world will be built from the library arguments plus these two. | 2550 // The world will be built from the library arguments plus these two. |
2519 final Map<ClassElement, _ReflectorDomain> domains = | 2551 final Map<ClassElement, _ReflectorDomain> domains = |
2520 <ClassElement, _ReflectorDomain>{}; | 2552 <ClassElement, _ReflectorDomain>{}; |
2521 final _ImportCollector importCollector = new _ImportCollector(); | 2553 final _ImportCollector importCollector = new _ImportCollector(); |
2522 | 2554 |
2523 // Maps each pattern to the list of reflectors associated with it via | 2555 // Maps each pattern to the list of reflectors associated with it via |
2524 // a [GlobalQuantifyCapability]. | 2556 // a [GlobalQuantifyCapability]. |
2525 Map<RegExp, List<ClassElement>> globalPatterns = | 2557 Map<RegExp, List<ClassElement>> globalPatterns = |
2526 <RegExp, List<ClassElement>>{}; | 2558 <RegExp, List<ClassElement>>{}; |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2733 } | 2765 } |
2734 | 2766 |
2735 /// Extracts the namePattern String from an instance of a subclass of | 2767 /// Extracts the namePattern String from an instance of a subclass of |
2736 /// NamePatternCapability. | 2768 /// NamePatternCapability. |
2737 String extractNamePattern(DartObjectImpl constant) { | 2769 String extractNamePattern(DartObjectImpl constant) { |
2738 if (constant.fields == null || | 2770 if (constant.fields == null || |
2739 constant.fields["(super)"] == null || | 2771 constant.fields["(super)"] == null || |
2740 constant.fields["(super)"].fields["namePattern"] == null || | 2772 constant.fields["(super)"].fields["namePattern"] == null || |
2741 constant.fields["(super)"].fields["namePattern"].toStringValue() == | 2773 constant.fields["(super)"].fields["namePattern"].toStringValue() == |
2742 null) { | 2774 null) { |
2743 // TODO(sigurdm) diagnostic: Better error-message. | 2775 // TODO(eernst) implement: Add location info to message. |
2744 _logger.warning("Could not extract namePattern."); | 2776 _warn(WarningKind.badNamePattern, |
2777 "Could not extract namePattern from capability."); | |
2778 return ""; | |
2745 } | 2779 } |
2746 return constant.fields["(super)"].fields["namePattern"].toStringValue(); | 2780 return constant.fields["(super)"].fields["namePattern"].toStringValue(); |
2747 } | 2781 } |
2748 | 2782 |
2749 /// Extracts the metadata property from an instance of a subclass of | 2783 /// Extracts the metadata property from an instance of a subclass of |
2750 /// MetadataCapability. | 2784 /// MetadataCapability. |
2751 ClassElement extractMetaData(DartObjectImpl constant) { | 2785 ClassElement extractMetaData(DartObjectImpl constant) { |
2752 if (constant.fields == null || | 2786 if (constant.fields == null || |
2753 constant.fields["(super)"] == null || | 2787 constant.fields["(super)"] == null || |
2754 constant.fields["(super)"].fields["metadataType"] == null) { | 2788 constant.fields["(super)"].fields["metadataType"] == null) { |
2755 // TODO(sigurdm) diagnostic: Better error-message. We need a way | 2789 // TODO(eernst) implement: Add location info to message. |
2756 // to get a source location from a constant. | 2790 _warn(WarningKind.badMetadata, |
2757 _logger.warning("Could not extract the metadata field."); | 2791 "Could not extract metadata type from capability."); |
2758 return null; | 2792 return null; |
2759 } | 2793 } |
2760 Object metadataFieldValue = constant.fields["(super)"].fields[ | 2794 Object metadataFieldValue = constant.fields["(super)"].fields[ |
2761 "metadataType"].toTypeValue().element; | 2795 "metadataType"].toTypeValue().element; |
2762 if (metadataFieldValue is! ClassElement) { | 2796 if (metadataFieldValue is! ClassElement) { |
2763 _logger.warning("The metadataType field must be a Type object."); | 2797 // TODO(eernst) implement: Add location info to message. |
2798 _warn(WarningKind.badMetadata, | |
2799 "Metadata specification in capability must be a `Type`."); | |
2764 return null; | 2800 return null; |
2765 } | 2801 } |
2766 return metadataFieldValue; | 2802 return metadataFieldValue; |
2767 } | 2803 } |
2768 | 2804 |
2769 switch (classElement.name) { | 2805 switch (classElement.name) { |
2770 case "_NameCapability": | 2806 case "_NameCapability": |
2771 return ec.nameCapability; | 2807 return ec.nameCapability; |
2772 case "_ClassifyCapability": | 2808 case "_ClassifyCapability": |
2773 return ec.classifyCapability; | 2809 return ec.classifyCapability; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2951 DartFormatter formatter = new DartFormatter(); | 2987 DartFormatter formatter = new DartFormatter(); |
2952 result = formatter.format(result); | 2988 result = formatter.format(result); |
2953 } | 2989 } |
2954 return result; | 2990 return result; |
2955 } | 2991 } |
2956 | 2992 |
2957 /// Performs the transformation which eliminates all imports of | 2993 /// Performs the transformation which eliminates all imports of |
2958 /// `package:reflectable/reflectable.dart` and instead provides a set of | 2994 /// `package:reflectable/reflectable.dart` and instead provides a set of |
2959 /// statically generated mirror classes. | 2995 /// statically generated mirror classes. |
2960 Future apply(AggregateTransform aggregateTransform, List<String> entryPoints, | 2996 Future apply(AggregateTransform aggregateTransform, List<String> entryPoints, |
2961 bool formatted) async { | 2997 bool formatted, List<WarningKind> suppressedWarnings) async { |
2962 _logger = aggregateTransform.logger; | 2998 _logger = aggregateTransform.logger; |
2963 _formatted = formatted; | 2999 _formatted = formatted; |
3000 _suppressedWarnings = suppressedWarnings; | |
2964 // The type argument in the return type is omitted because the | 3001 // The type argument in the return type is omitted because the |
2965 // documentation on barback and on transformers do not specify it. | 3002 // documentation on barback and on transformers do not specify it. |
2966 | 3003 |
2967 List<Asset> assets = await aggregateTransform.primaryInputs.toList(); | 3004 List<Asset> assets = await aggregateTransform.primaryInputs.toList(); |
2968 | 3005 |
2969 if (assets.isEmpty) { | 3006 if (assets.isEmpty) { |
2970 // It is not an error to have nothing to transform. | 3007 // It is not an error to have nothing to transform. |
2971 _logger.info("Nothing to transform"); | 3008 _logger.info("Nothing to transform"); |
2972 // Terminate with a non-failing status code to the OS. | 3009 // Terminate with a non-failing status code to the OS. |
2973 exit(0); | 3010 exit(0); |
2974 } | 3011 } |
2975 | 3012 |
2976 // TODO(eernst) algorithm: Build a mapping from entry points to assets by | 3013 // TODO(eernst) algorithm: Build a mapping from entry points to assets by |
2977 // iterating over `assets` and doing a binary search on a sorted | 3014 // iterating over `assets` and doing a binary search on a sorted |
2978 // list of entry points: if A is the number of assets and E is the | 3015 // list of entry points: if A is the number of assets and E is the |
2979 // number of entry points (note: E < A, and E == 1 could be quite | 3016 // number of entry points (note: E < A, and E == 1 could be quite |
2980 // common), this would cost O(A*log(E)), whereas the current | 3017 // common), this would cost O(A*log(E)), whereas the current |
2981 // approach costs O(A*E). OK, it's log(E)+epsilon, not 0 when E == 1. | 3018 // approach costs O(A*E). OK, it's log(E)+epsilon, not 0 when E == 1. |
2982 for (String entryPoint in entryPoints) { | 3019 for (String entryPoint in entryPoints) { |
2983 // Find the asset corresponding to [entryPoint] | 3020 // Find the asset corresponding to [entryPoint] |
2984 Asset entryPointAsset = assets.firstWhere( | 3021 Asset entryPointAsset = assets.firstWhere( |
2985 (Asset asset) => asset.id.path.endsWith(entryPoint), | 3022 (Asset asset) => asset.id.path.endsWith(entryPoint), |
2986 orElse: () => null); | 3023 orElse: () => null); |
2987 if (entryPointAsset == null) { | 3024 if (entryPointAsset == null) { |
2988 aggregateTransform.logger.info("Missing entry point: $entryPoint"); | 3025 if (_warningEnabled(WarningKind.missingEntryPoint)) { |
3026 String entryPointPath = | |
3027 entryPoint.split('/').join(Platform.pathSeparator); | |
3028 bool entryPointFileExists = await new File(entryPointPath).exists(); | |
3029 if (!entryPointFileExists) { | |
3030 // We did not receive an asset for [entryPoint], and there is no | |
3031 // corresponding file (so it is not just because we were invoked | |
3032 // from `pub build test` and [entryPoint] is in `web`, or something | |
3033 // similar). Announce the problem. | |
3034 aggregateTransform.logger | |
3035 .warning("Missing entry point: $entryPoint"); | |
3036 } | |
3037 } | |
2989 continue; | 3038 continue; |
2990 } | 3039 } |
2991 Transform wrappedTransform = | 3040 Transform wrappedTransform = |
2992 new _AggregateTransformWrapper(aggregateTransform, entryPointAsset); | 3041 new _AggregateTransformWrapper(aggregateTransform, entryPointAsset); |
2993 | 3042 |
2994 _resolver = await _resolvers.get(wrappedTransform); | 3043 _resolver = await _resolvers.get(wrappedTransform); |
2995 LibraryElement reflectableLibrary = | 3044 LibraryElement reflectableLibrary = |
2996 _resolver.getLibraryByName("reflectable.reflectable"); | 3045 _resolver.getLibraryByName("reflectable.reflectable"); |
2997 if (reflectableLibrary == null) { | 3046 if (reflectableLibrary == null) { |
2998 // Stop and do not consumePrimary, i.e., let the original source | 3047 // Stop and do not consumePrimary, i.e., let the original source |
(...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4058 return functionElement == null | 4107 return functionElement == null |
4059 ? "null" | 4108 ? "null" |
4060 : "${functionElement.library.name}.${functionElement.name}"; | 4109 : "${functionElement.library.name}.${functionElement.name}"; |
4061 } | 4110 } |
4062 | 4111 |
4063 String _qualifiedTypeParameterName(TypeParameterElement typeParameterElement) { | 4112 String _qualifiedTypeParameterName(TypeParameterElement typeParameterElement) { |
4064 if (typeParameterElement == null) return "null"; | 4113 if (typeParameterElement == null) return "null"; |
4065 return "${_qualifiedName(typeParameterElement.enclosingElement)}." | 4114 return "${_qualifiedName(typeParameterElement.enclosingElement)}." |
4066 "${typeParameterElement.name}"; | 4115 "${typeParameterElement.name}"; |
4067 } | 4116 } |
OLD | NEW |