Chromium Code Reviews| 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 296 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, |
| 976 Enumerator<ExecutableElement> members, | 997 Enumerator<ExecutableElement> members, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1011 if (_capabilities._impliesDeclarations) { | 1032 if (_capabilities._impliesDeclarations) { |
| 1012 List<int> declarationsIndices = <int>[] | 1033 List<int> declarationsIndices = <int>[] |
| 1013 ..addAll(variableIndices) | 1034 ..addAll(variableIndices) |
| 1014 ..addAll(methodsIndices); | 1035 ..addAll(methodsIndices); |
| 1015 declarationsCode = _formatAsConstList("int", declarationsIndices); | 1036 declarationsCode = _formatAsConstList("int", declarationsIndices); |
| 1016 } | 1037 } |
| 1017 | 1038 |
| 1018 // TODO(sigurdm) clarify: Find out how to get good uri's in a | 1039 // TODO(sigurdm) clarify: Find out how to get good uri's in a |
| 1019 // transformer. | 1040 // transformer. |
| 1020 // TODO(sigurdm) implement: Check for `uriCapability`. | 1041 // TODO(sigurdm) implement: Check for `uriCapability`. |
| 1021 String uriCode = "null"; | 1042 String uriCode = 'Uri.parse(r"reflectable://$library")'; |
|
sigurdm
2015/10/15 12:30:58
Is this any better?
eernst
2015/10/15 13:46:11
We cannot implement a map from `Uri` to `LibraryMi
| |
| 1022 | 1043 |
| 1023 String metadataCode; | 1044 String metadataCode; |
| 1024 if (_capabilities._supportsMetadata) { | 1045 if (_capabilities._supportsMetadata) { |
| 1025 metadataCode = _extractMetadataCode( | 1046 metadataCode = _extractMetadataCode( |
| 1026 library, _resolver, importCollector, logger, _generatedLibraryId); | 1047 library, _resolver, importCollector, logger, _generatedLibraryId); |
| 1027 } else { | 1048 } else { |
| 1028 metadataCode = "null"; | 1049 metadataCode = "null"; |
| 1029 } | 1050 } |
| 1030 | 1051 |
| 1031 return 'new r.LibraryMirrorImpl(r"${library.name}", $uriCode, ' | 1052 return 'new r.LibraryMirrorImpl(r"${library.name}", $uriCode, ' |
| (...skipping 1245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2277 assert(_isImportableLibrary(reflector.library, dataId, _resolver)); | 2298 assert(_isImportableLibrary(reflector.library, dataId, _resolver)); |
| 2278 importCollector._addLibrary(reflector.library); | 2299 importCollector._addLibrary(reflector.library); |
| 2279 return new _ReflectorDomain(_resolver, dataId, reflector, capabilities); | 2300 return new _ReflectorDomain(_resolver, dataId, reflector, capabilities); |
| 2280 }); | 2301 }); |
| 2281 } | 2302 } |
| 2282 | 2303 |
| 2283 /// Adds [library] to the supported libraries of [reflector]. | 2304 /// Adds [library] to the supported libraries of [reflector]. |
| 2284 void addLibrary(LibraryElement library, ClassElement reflector) { | 2305 void addLibrary(LibraryElement library, ClassElement reflector) { |
| 2285 _ReflectorDomain domain = getReflectorDomain(reflector); | 2306 _ReflectorDomain domain = getReflectorDomain(reflector); |
| 2286 if (domain._capabilities.supportsLibraries) { | 2307 if (domain._capabilities.supportsLibraries) { |
| 2287 assert(_isImportableLibrary(reflector.library, dataId, _resolver)); | 2308 assert(_isImportableLibrary(library, dataId, _resolver)); |
| 2288 importCollector._addLibrary(library); | 2309 importCollector._addLibrary(library); |
| 2289 domain._libraries.add(library); | 2310 domain._libraries.add(library); |
| 2290 } | 2311 } |
| 2291 } | 2312 } |
| 2292 | 2313 |
| 2293 /// Adds a [_ClassDomain] representing [type] to the supported classes of | 2314 /// Adds a [_ClassDomain] representing [type] to the supported classes of |
| 2294 /// [reflector]; also adds the enclosing library of [type] to the | 2315 /// [reflector]; also adds the enclosing library of [type] to the |
| 2295 /// supported libraries. | 2316 /// supported libraries. |
| 2296 void addClassDomain(ClassElement type, ClassElement reflector) { | 2317 void addClassDomain(ClassElement type, ClassElement reflector) { |
| 2297 if (!_isImportable(type, dataId, _resolver)) { | 2318 if (!_isImportable(type, dataId, _resolver)) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2380 | 2401 |
| 2381 // Populate [globalPatterns] and [globalMetadata]. | 2402 // Populate [globalPatterns] and [globalMetadata]. |
| 2382 _findGlobalQuantifyAnnotations(globalPatterns, globalMetadata); | 2403 _findGlobalQuantifyAnnotations(globalPatterns, globalMetadata); |
| 2383 | 2404 |
| 2384 // Visits all libraries and all classes in the given entry point, | 2405 // Visits all libraries and all classes in the given entry point, |
| 2385 // gets their reflectors, and adds them to the domain of that | 2406 // gets their reflectors, and adds them to the domain of that |
| 2386 // reflector. | 2407 // reflector. |
| 2387 for (LibraryElement library in _resolver.libraries) { | 2408 for (LibraryElement library in _resolver.libraries) { |
| 2388 for (ClassElement reflector | 2409 for (ClassElement reflector |
| 2389 in getReflectors(library.name, library.metadata)) { | 2410 in getReflectors(library.name, library.metadata)) { |
| 2390 assert(_isImportableLibrary(reflector.library, dataId, _resolver)); | 2411 assert(_isImportableLibrary(library, dataId, _resolver)); |
| 2391 addLibrary(library, reflector); | 2412 addLibrary(library, reflector); |
| 2392 } | 2413 } |
| 2393 | 2414 |
| 2394 for (CompilationUnitElement unit in library.units) { | 2415 for (CompilationUnitElement unit in library.units) { |
| 2395 for (ClassElement type in unit.types) { | 2416 for (ClassElement type in unit.types) { |
| 2396 for (ClassElement reflector | 2417 for (ClassElement reflector |
| 2397 in getReflectors(_qualifiedName(type), type.metadata)) { | 2418 in getReflectors(_qualifiedName(type), type.metadata)) { |
| 2398 addClassDomain(type, reflector); | 2419 addClassDomain(type, reflector); |
| 2399 } | 2420 } |
| 2400 } | 2421 } |
| (...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3684 return classElement == null | 3705 return classElement == null |
| 3685 ? "null" | 3706 ? "null" |
| 3686 : "${classElement.library.name}.${classElement.name}"; | 3707 : "${classElement.library.name}.${classElement.name}"; |
| 3687 } | 3708 } |
| 3688 | 3709 |
| 3689 String _qualifiedFunctionName(FunctionElement functionElement) { | 3710 String _qualifiedFunctionName(FunctionElement functionElement) { |
| 3690 return functionElement == null | 3711 return functionElement == null |
| 3691 ? "null" | 3712 ? "null" |
| 3692 : "${functionElement.library.name}.${functionElement.name}"; | 3713 : "${functionElement.library.name}.${functionElement.name}"; |
| 3693 } | 3714 } |
| OLD | NEW |