| 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:io'; | 9 import 'dart:io'; |
| 10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/src/generated/ast.dart'; |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 Iterable<_ClassDomain> get domains => elementToDomain.values; | 357 Iterable<_ClassDomain> get domains => elementToDomain.values; |
| 358 } | 358 } |
| 359 | 359 |
| 360 /// Information about the program parts that can be reflected by a given | 360 /// Information about the program parts that can be reflected by a given |
| 361 /// Reflector. | 361 /// Reflector. |
| 362 class _ReflectorDomain { | 362 class _ReflectorDomain { |
| 363 final Resolver _resolver; | 363 final Resolver _resolver; |
| 364 final AssetId _generatedLibraryId; | 364 final AssetId _generatedLibraryId; |
| 365 final ClassElement _reflector; | 365 final ClassElement _reflector; |
| 366 | 366 |
| 367 /// Do not use this, use [classes] which ensures that closures operations | 367 /// Do not use this, use [classes] which ensures that closure operations |
| 368 /// have been performed as requested in [_capabilities]. Exception: In | 368 /// have been performed as requested in [_capabilities]. Exception: In |
| 369 /// `_computeWorld`, [_classes] is filled in with the set of directly | 369 /// `_computeWorld`, [_classes] is filled in with the set of directly |
| 370 /// covered classes during creation of this [_ReflectorDomain]. | 370 /// covered classes during creation of this [_ReflectorDomain]. |
| 371 /// NB: [_classes] should be final, but it is not possible because this | 371 /// NB: [_classes] should be final, but it is not possible because this |
| 372 /// would create a cycle of final fields, which cannot be initialized. | 372 /// would create a cycle of final fields, which cannot be initialized. |
| 373 ClassElementEnhancedSet _classes; | 373 ClassElementEnhancedSet _classes; |
| 374 | 374 |
| 375 /// Used by [classes], only, to keep track of whether [_classes] has been | 375 /// Used by [classes], only, to keep track of whether [_classes] has been |
| 376 /// properly initialized by means of closure operations. | 376 /// properly initialized by means of closure operations. |
| 377 bool _classesInitialized = false; | 377 bool _classesInitialized = false; |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 // Class related collections. | 535 // Class related collections. |
| 536 Enumerator<FieldElement> fields = new Enumerator<FieldElement>(); | 536 Enumerator<FieldElement> fields = new Enumerator<FieldElement>(); |
| 537 Enumerator<ParameterElement> parameters = | 537 Enumerator<ParameterElement> parameters = |
| 538 new Enumerator<ParameterElement>(); | 538 new Enumerator<ParameterElement>(); |
| 539 Set<String> instanceGetterNames = new Set<String>(); | 539 Set<String> instanceGetterNames = new Set<String>(); |
| 540 Set<String> instanceSetterNames = new Set<String>(); | 540 Set<String> instanceSetterNames = new Set<String>(); |
| 541 | 541 |
| 542 // Library and class related collections. | 542 // Library and class related collections. |
| 543 Enumerator<ExecutableElement> members = new Enumerator<ExecutableElement>(); | 543 Enumerator<ExecutableElement> members = new Enumerator<ExecutableElement>(); |
| 544 | 544 |
| 545 // Fill in [libraries], [members], [fields], [parameters], | 545 /// Adds a library domain for [library] to [libraries], relying on checks |
| 546 // [instanceGetterNames], and [instanceSetterNames]. | 546 /// for importability and insertion into [importCollector] to have taken |
| 547 for (LibraryElement library in _libraries) { | 547 /// place already. |
| 548 void uncheckedAddLibrary(LibraryElement library) { |
| 548 _LibraryDomain libraryDomain = _createLibraryDomain(library, this); | 549 _LibraryDomain libraryDomain = _createLibraryDomain(library, this); |
| 549 libraries.add(libraryDomain); | 550 libraries.add(libraryDomain); |
| 550 libraryMap[library] = libraryDomain; | 551 libraryMap[library] = libraryDomain; |
| 551 libraryDomain._declarations.forEach(members.add); | 552 libraryDomain._declarations.forEach(members.add); |
| 552 libraryDomain._declaredParameters.forEach(parameters.add); | 553 libraryDomain._declaredParameters.forEach(parameters.add); |
| 553 libraryDomain._declaredVariables.forEach(topLevelVariables.add); | 554 libraryDomain._declaredVariables.forEach(topLevelVariables.add); |
| 554 } | 555 } |
| 556 |
| 557 /// Used to add a library domain for [library] to [libraries], checking |
| 558 /// that it is importable and registering it with [importCollector]. |
| 559 void addLibrary(LibraryElement library) { |
| 560 if (!_isImportableLibrary( |
| 561 library, _generatedLibraryId, _resolver)) return; |
| 562 importCollector._addLibrary(library); |
| 563 uncheckedAddLibrary(library); |
| 564 } |
| 565 |
| 566 // Fill in [libraries], [members], [fields], [parameters], |
| 567 // [instanceGetterNames], and [instanceSetterNames]. |
| 568 _libraries.forEach(uncheckedAddLibrary); |
| 569 classes.forEach((ClassElement classElement) { |
| 570 if (!libraries.items.any((_LibraryDomain libraryDomain) => |
| 571 libraryDomain._libraryElement == classElement.library)) { |
| 572 addLibrary(classElement.library); |
| 573 } |
| 574 }); |
| 555 for (_ClassDomain classDomain in classes.domains) { | 575 for (_ClassDomain classDomain in classes.domains) { |
| 556 // Gather the behavioral interface into [members]. Note that | 576 // Gather the behavioral interface into [members]. Note that |
| 557 // this includes implicitly generated getters and setters, but | 577 // this includes implicitly generated getters and setters, but |
| 558 // omits fields. Also note that this does not match the | 578 // omits fields. Also note that this does not match the |
| 559 // semantics of the `declarations` method in a [ClassMirror]. | 579 // semantics of the `declarations` method in a [ClassMirror]. |
| 560 classDomain._declarations.forEach(members.add); | 580 classDomain._declarations.forEach(members.add); |
| 561 | 581 |
| 562 // Add the behavioral interface from this class (redundantly, for | 582 // Add the behavioral interface from this class (redundantly, for |
| 563 // non-static members) and all superclasses (which matters) to | 583 // non-static members) and all superclasses (which matters) to |
| 564 // [members], such that it contains both the behavioral parts for | 584 // [members], such that it contains both the behavioral parts for |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 return _typeCodeOfClass(classElement, importCollector); | 670 return _typeCodeOfClass(classElement, importCollector); |
| 651 })); | 671 })); |
| 652 | 672 |
| 653 // Generate code for creation of library mirrors. | 673 // Generate code for creation of library mirrors. |
| 654 String librariesCode; | 674 String librariesCode; |
| 655 if (!_capabilities.supportsLibraries) { | 675 if (!_capabilities.supportsLibraries) { |
| 656 librariesCode = "null"; | 676 librariesCode = "null"; |
| 657 } else { | 677 } else { |
| 658 librariesCode = _formatAsList("m.LibraryMirror", | 678 librariesCode = _formatAsList("m.LibraryMirror", |
| 659 libraries.items.map((_LibraryDomain library) { | 679 libraries.items.map((_LibraryDomain library) { |
| 660 return _libraryMirrorCode(library, members, topLevelVariables, | 680 return _libraryMirrorCode(library, libraries.indexOf(library), members, |
| 661 fields.length, importCollector, logger); | 681 topLevelVariables, fields.length, importCollector, logger); |
| 662 })); | 682 })); |
| 663 } | 683 } |
| 664 | 684 |
| 665 // Generate code for creation of parameter mirrors. | 685 // Generate code for creation of parameter mirrors. |
| 666 Iterable<String> parametersList = | 686 Iterable<String> parametersList = |
| 667 parameters.items.map((ParameterElement element) { | 687 parameters.items.map((ParameterElement element) { |
| 668 return _parameterMirrorCode(element, fields, members, importCollector, | 688 return _parameterMirrorCode(element, fields, members, importCollector, |
| 669 logger, reflectedTypeRequested); | 689 logger, reflectedTypeRequested); |
| 670 }); | 690 }); |
| 671 String parameterMirrorsCode = | 691 String parameterMirrorsCode = |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 String classMetadataCode; | 881 String classMetadataCode; |
| 862 if (_capabilities._supportsMetadata) { | 882 if (_capabilities._supportsMetadata) { |
| 863 classMetadataCode = _extractMetadataCode(classElement, _resolver, | 883 classMetadataCode = _extractMetadataCode(classElement, _resolver, |
| 864 importCollector, logger, _generatedLibraryId); | 884 importCollector, logger, _generatedLibraryId); |
| 865 } else { | 885 } else { |
| 866 classMetadataCode = "null"; | 886 classMetadataCode = "null"; |
| 867 } | 887 } |
| 868 | 888 |
| 869 int classIndex = classes.indexOf(classElement); | 889 int classIndex = classes.indexOf(classElement); |
| 870 | 890 |
| 871 String result = 'new r.ClassMirrorImpl(r"${classDomain._simpleName}", ' | 891 return 'new r.ClassMirrorImpl(r"${classDomain._simpleName}", ' |
| 872 'r"${_qualifiedName(classElement)}", $descriptor, $classIndex, ' | 892 'r"${_qualifiedName(classElement)}", $descriptor, $classIndex, ' |
| 873 '${_constConstructionCode(importCollector)}, ' | 893 '${_constConstructionCode(importCollector)}, ' |
| 874 '$declarationsCode, $instanceMembersCode, $staticMembersCode, ' | 894 '$declarationsCode, $instanceMembersCode, $staticMembersCode, ' |
| 875 '$superclassIndex, $staticGettersCode, $staticSettersCode, ' | 895 '$superclassIndex, $staticGettersCode, $staticSettersCode, ' |
| 876 '$constructorsCode, $ownerIndex, $mixinIndex, ' | 896 '$constructorsCode, $ownerIndex, $mixinIndex, ' |
| 877 '$superinterfaceIndices, $classMetadataCode)'; | 897 '$superinterfaceIndices, $classMetadataCode)'; |
| 878 return result; | |
| 879 } | 898 } |
| 880 | 899 |
| 881 String _methodMirrorCode( | 900 String _methodMirrorCode( |
| 882 ExecutableElement element, | 901 ExecutableElement element, |
| 883 Enumerator<FieldElement> fields, | 902 Enumerator<FieldElement> fields, |
| 884 Enumerator<ExecutableElement> members, | 903 Enumerator<ExecutableElement> members, |
| 885 Enumerator<ParameterElement> parameters, | 904 Enumerator<ParameterElement> parameters, |
| 886 _ImportCollector importCollector, | 905 _ImportCollector importCollector, |
| 887 TransformLogger logger, | 906 TransformLogger logger, |
| 888 bool reflectedTypeRequested) { | 907 bool reflectedTypeRequested) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 956 if (dartType is TypeParameterType) { | 975 if (dartType is TypeParameterType) { |
| 957 ClassElement owningClassElement = dartType.element.enclosingElement; | 976 ClassElement owningClassElement = dartType.element.enclosingElement; |
| 958 return 'const r.FakeType(r"${_qualifiedName(owningClassElement)}.' | 977 return 'const r.FakeType(r"${_qualifiedName(owningClassElement)}.' |
| 959 '${dartType.element}")'; | 978 '${dartType.element}")'; |
| 960 } | 979 } |
| 961 return _typeCodeOfClass(dartType.element, importCollector); | 980 return _typeCodeOfClass(dartType.element, importCollector); |
| 962 } | 981 } |
| 963 | 982 |
| 964 String _typeCodeOfClass( | 983 String _typeCodeOfClass( |
| 965 ClassElement classElement, _ImportCollector importCollector) { | 984 ClassElement classElement, _ImportCollector importCollector) { |
| 966 if (classElement is MixinApplication && classElement.declaredName == null) { | 985 if ((classElement is MixinApplication && |
| 986 classElement.declaredName == null) || |
| 987 classElement.isPrivate) { |
| 967 return 'const r.FakeType(r"${_qualifiedName(classElement)}")'; | 988 return 'const r.FakeType(r"${_qualifiedName(classElement)}")'; |
| 968 } | 989 } |
| 969 if (classElement.type.isDynamic) return "dynamic"; | 990 if (classElement.type.isDynamic) return "dynamic"; |
| 970 String prefix = importCollector._getPrefix(classElement.library); | 991 String prefix = importCollector._getPrefix(classElement.library); |
| 971 return "$prefix.${classElement.name}"; | 992 return "$prefix.${classElement.name}"; |
| 972 } | 993 } |
| 973 | 994 |
| 974 String _libraryMirrorCode( | 995 String _libraryMirrorCode( |
| 975 _LibraryDomain libraryDomain, | 996 _LibraryDomain libraryDomain, |
| 997 int libraryIndex, |
| 976 Enumerator<ExecutableElement> members, | 998 Enumerator<ExecutableElement> members, |
| 977 Enumerator<TopLevelVariableElement> variables, | 999 Enumerator<TopLevelVariableElement> variables, |
| 978 int fieldsLength, | 1000 int fieldsLength, |
| 979 _ImportCollector importCollector, | 1001 _ImportCollector importCollector, |
| 980 TransformLogger logger) { | 1002 TransformLogger logger) { |
| 981 LibraryElement library = libraryDomain._libraryElement; | 1003 LibraryElement library = libraryDomain._libraryElement; |
| 982 | 1004 |
| 983 String gettersCode = _formatAsMap( | 1005 String gettersCode = _formatAsMap( |
| 984 _gettersOfLibrary(libraryDomain).map((PropertyAccessorElement getter) { | 1006 _gettersOfLibrary(libraryDomain).map((PropertyAccessorElement getter) { |
| 985 return _topLevelGettingClosure(importCollector, library, getter.name); | 1007 return _topLevelGettingClosure(importCollector, library, getter.name); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1010 String declarationsCode = "const <int>[${constants.NO_CAPABILITY_INDEX}]"; | 1032 String declarationsCode = "const <int>[${constants.NO_CAPABILITY_INDEX}]"; |
| 1011 if (_capabilities._impliesDeclarations) { | 1033 if (_capabilities._impliesDeclarations) { |
| 1012 List<int> declarationsIndices = <int>[] | 1034 List<int> declarationsIndices = <int>[] |
| 1013 ..addAll(variableIndices) | 1035 ..addAll(variableIndices) |
| 1014 ..addAll(methodsIndices); | 1036 ..addAll(methodsIndices); |
| 1015 declarationsCode = _formatAsConstList("int", declarationsIndices); | 1037 declarationsCode = _formatAsConstList("int", declarationsIndices); |
| 1016 } | 1038 } |
| 1017 | 1039 |
| 1018 // TODO(sigurdm) clarify: Find out how to get good uri's in a | 1040 // TODO(sigurdm) clarify: Find out how to get good uri's in a |
| 1019 // transformer. | 1041 // transformer. |
| 1020 // TODO(sigurdm) implement: Check for `uriCapability`. | 1042 String uriCode = (_capabilities._supportsUri || |
| 1021 String uriCode = "null"; | 1043 _capabilities.supportsLibraries) |
| 1044 ? 'Uri.parse(r"reflectable://$libraryIndex/$library")' |
| 1045 : 'null'; |
| 1022 | 1046 |
| 1023 String metadataCode; | 1047 String metadataCode; |
| 1024 if (_capabilities._supportsMetadata) { | 1048 if (_capabilities._supportsMetadata) { |
| 1025 metadataCode = _extractMetadataCode( | 1049 metadataCode = _extractMetadataCode( |
| 1026 library, _resolver, importCollector, logger, _generatedLibraryId); | 1050 library, _resolver, importCollector, logger, _generatedLibraryId); |
| 1027 } else { | 1051 } else { |
| 1028 metadataCode = "null"; | 1052 metadataCode = "null"; |
| 1029 } | 1053 } |
| 1030 | 1054 |
| 1031 return 'new r.LibraryMirrorImpl(r"${library.name}", $uriCode, ' | 1055 return 'new r.LibraryMirrorImpl(r"${library.name}", $uriCode, ' |
| (...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1849 methodName, | 1873 methodName, |
| 1850 _getEvaluatedMetadata(metadata), | 1874 _getEvaluatedMetadata(metadata), |
| 1851 getterMetadata == null ? null : _getEvaluatedMetadata(getterMetadata)); | 1875 getterMetadata == null ? null : _getEvaluatedMetadata(getterMetadata)); |
| 1852 } | 1876 } |
| 1853 | 1877 |
| 1854 bool get _supportsMetadata { | 1878 bool get _supportsMetadata { |
| 1855 return _capabilities.any((ec.ReflectCapability capability) => | 1879 return _capabilities.any((ec.ReflectCapability capability) => |
| 1856 capability == ec.metadataCapability); | 1880 capability == ec.metadataCapability); |
| 1857 } | 1881 } |
| 1858 | 1882 |
| 1883 bool get _supportsUri { |
| 1884 return _capabilities.any( |
| 1885 (ec.ReflectCapability capability) => capability == ec.uriCapability); |
| 1886 } |
| 1887 |
| 1859 /// Returns [true] iff these [Capabilities] specify reflection support | 1888 /// Returns [true] iff these [Capabilities] specify reflection support |
| 1860 /// where the set of classes must be downwards closed, i.e., extra classes | 1889 /// where the set of classes must be downwards closed, i.e., extra classes |
| 1861 /// must be added beyond the ones that are directly covered by the given | 1890 /// must be added beyond the ones that are directly covered by the given |
| 1862 /// metadata and global quantifiers, such that coverage on a class `C` | 1891 /// metadata and global quantifiers, such that coverage on a class `C` |
| 1863 /// implies coverage of every class `D` such that `D` is a subtype of `C`. | 1892 /// implies coverage of every class `D` such that `D` is a subtype of `C`. |
| 1864 bool get _impliesDownwardsClosure { | 1893 bool get _impliesDownwardsClosure { |
| 1865 return _capabilities.any((ec.ReflectCapability capability) => | 1894 return _capabilities.any((ec.ReflectCapability capability) => |
| 1866 capability == ec.subtypeQuantifyCapability); | 1895 capability == ec.subtypeQuantifyCapability); |
| 1867 } | 1896 } |
| 1868 | 1897 |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2277 assert(_isImportableLibrary(reflector.library, dataId, _resolver)); | 2306 assert(_isImportableLibrary(reflector.library, dataId, _resolver)); |
| 2278 importCollector._addLibrary(reflector.library); | 2307 importCollector._addLibrary(reflector.library); |
| 2279 return new _ReflectorDomain(_resolver, dataId, reflector, capabilities); | 2308 return new _ReflectorDomain(_resolver, dataId, reflector, capabilities); |
| 2280 }); | 2309 }); |
| 2281 } | 2310 } |
| 2282 | 2311 |
| 2283 /// Adds [library] to the supported libraries of [reflector]. | 2312 /// Adds [library] to the supported libraries of [reflector]. |
| 2284 void addLibrary(LibraryElement library, ClassElement reflector) { | 2313 void addLibrary(LibraryElement library, ClassElement reflector) { |
| 2285 _ReflectorDomain domain = getReflectorDomain(reflector); | 2314 _ReflectorDomain domain = getReflectorDomain(reflector); |
| 2286 if (domain._capabilities.supportsLibraries) { | 2315 if (domain._capabilities.supportsLibraries) { |
| 2287 assert(_isImportableLibrary(reflector.library, dataId, _resolver)); | 2316 assert(_isImportableLibrary(library, dataId, _resolver)); |
| 2288 importCollector._addLibrary(library); | 2317 importCollector._addLibrary(library); |
| 2289 domain._libraries.add(library); | 2318 domain._libraries.add(library); |
| 2290 } | 2319 } |
| 2291 } | 2320 } |
| 2292 | 2321 |
| 2293 /// Adds a [_ClassDomain] representing [type] to the supported classes of | 2322 /// Adds a [_ClassDomain] representing [type] to the supported classes of |
| 2294 /// [reflector]; also adds the enclosing library of [type] to the | 2323 /// [reflector]; also adds the enclosing library of [type] to the |
| 2295 /// supported libraries. | 2324 /// supported libraries. |
| 2296 void addClassDomain(ClassElement type, ClassElement reflector) { | 2325 void addClassDomain(ClassElement type, ClassElement reflector) { |
| 2297 if (!_isImportable(type, dataId, _resolver)) { | 2326 if (!_isImportable(type, dataId, _resolver)) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2380 | 2409 |
| 2381 // Populate [globalPatterns] and [globalMetadata]. | 2410 // Populate [globalPatterns] and [globalMetadata]. |
| 2382 _findGlobalQuantifyAnnotations(globalPatterns, globalMetadata); | 2411 _findGlobalQuantifyAnnotations(globalPatterns, globalMetadata); |
| 2383 | 2412 |
| 2384 // Visits all libraries and all classes in the given entry point, | 2413 // Visits all libraries and all classes in the given entry point, |
| 2385 // gets their reflectors, and adds them to the domain of that | 2414 // gets their reflectors, and adds them to the domain of that |
| 2386 // reflector. | 2415 // reflector. |
| 2387 for (LibraryElement library in _resolver.libraries) { | 2416 for (LibraryElement library in _resolver.libraries) { |
| 2388 for (ClassElement reflector | 2417 for (ClassElement reflector |
| 2389 in getReflectors(library.name, library.metadata)) { | 2418 in getReflectors(library.name, library.metadata)) { |
| 2390 assert(_isImportableLibrary(reflector.library, dataId, _resolver)); | 2419 assert(_isImportableLibrary(library, dataId, _resolver)); |
| 2391 addLibrary(library, reflector); | 2420 addLibrary(library, reflector); |
| 2392 } | 2421 } |
| 2393 | 2422 |
| 2394 for (CompilationUnitElement unit in library.units) { | 2423 for (CompilationUnitElement unit in library.units) { |
| 2395 for (ClassElement type in unit.types) { | 2424 for (ClassElement type in unit.types) { |
| 2396 for (ClassElement reflector | 2425 for (ClassElement reflector |
| 2397 in getReflectors(_qualifiedName(type), type.metadata)) { | 2426 in getReflectors(_qualifiedName(type), type.metadata)) { |
| 2398 addClassDomain(type, reflector); | 2427 addClassDomain(type, reflector); |
| 2399 } | 2428 } |
| 2400 } | 2429 } |
| (...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3684 return classElement == null | 3713 return classElement == null |
| 3685 ? "null" | 3714 ? "null" |
| 3686 : "${classElement.library.name}.${classElement.name}"; | 3715 : "${classElement.library.name}.${classElement.name}"; |
| 3687 } | 3716 } |
| 3688 | 3717 |
| 3689 String _qualifiedFunctionName(FunctionElement functionElement) { | 3718 String _qualifiedFunctionName(FunctionElement functionElement) { |
| 3690 return functionElement == null | 3719 return functionElement == null |
| 3691 ? "null" | 3720 ? "null" |
| 3692 : "${functionElement.library.name}.${functionElement.name}"; | 3721 : "${functionElement.library.name}.${functionElement.name}"; |
| 3693 } | 3722 } |
| OLD | NEW |