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 |