| Index: reflectable/lib/src/transformer_implementation.dart
|
| diff --git a/reflectable/lib/src/transformer_implementation.dart b/reflectable/lib/src/transformer_implementation.dart
|
| index 8bb6decee619f24e8f7f1b4d11f491640db0e8f2..26b99b83a8ff017dd20a981a25c34ed6e47cbe6e 100644
|
| --- a/reflectable/lib/src/transformer_implementation.dart
|
| +++ b/reflectable/lib/src/transformer_implementation.dart
|
| @@ -525,18 +525,32 @@ class _ReflectorDomain {
|
| /// `_reflector` to behave correctly.
|
| String _generateCode(
|
| _ImportCollector importCollector, TransformLogger logger) {
|
| - Enumerator<ExecutableElement> members = new Enumerator<ExecutableElement>();
|
| + // Library related collections.
|
| + Enumerator<_LibraryDomain> libraries = new Enumerator<_LibraryDomain>();
|
| + Map<LibraryElement, _LibraryDomain> libraryMap =
|
| + <LibraryElement, _LibraryDomain>{};
|
| + Enumerator<TopLevelVariableElement> topLevelVariables =
|
| + new Enumerator<TopLevelVariableElement>();
|
| +
|
| + // Class related collections.
|
| Enumerator<FieldElement> fields = new Enumerator<FieldElement>();
|
| Enumerator<ParameterElement> parameters =
|
| new Enumerator<ParameterElement>();
|
| - Enumerator<LibraryElement> libraries = new Enumerator<LibraryElement>();
|
| Set<String> instanceGetterNames = new Set<String>();
|
| Set<String> instanceSetterNames = new Set<String>();
|
|
|
| + // Library and class related collections.
|
| + Enumerator<ExecutableElement> members = new Enumerator<ExecutableElement>();
|
| +
|
| // Fill in [libraries], [members], [fields], [parameters],
|
| // [instanceGetterNames], and [instanceSetterNames].
|
| for (LibraryElement library in _libraries) {
|
| - libraries.add(library);
|
| + _LibraryDomain libraryDomain = _createLibraryDomain(library, this);
|
| + libraries.add(libraryDomain);
|
| + libraryMap[library] = libraryDomain;
|
| + libraryDomain._declarations.forEach(members.add);
|
| + libraryDomain._declaredParameters.forEach(parameters.add);
|
| + libraryDomain._declaredVariables.forEach(topLevelVariables.add);
|
| }
|
| for (_ClassDomain classDomain in classes.domains) {
|
| // Gather the behavioral interface into [members]. Note that
|
| @@ -588,13 +602,25 @@ class _ReflectorDomain {
|
| });
|
| }
|
|
|
| + // Find the offsets of fields and of methods and functions in members.
|
| + int fieldsOffset = topLevelVariables.length;
|
| + int methodsOffset = fieldsOffset + fields.length;
|
| +
|
| // Generate code for creation of class mirrors.
|
| String classMirrorsCode = _formatAsList(
|
| "m.ClassMirror",
|
| _capabilities._impliesTypes
|
| ? classes.domains.map((_ClassDomain classDomain) =>
|
| - _classMirrorCode(classDomain, fields, members, libraries,
|
| - importCollector, logger))
|
| + _classMirrorCode(
|
| + classDomain,
|
| + fields,
|
| + fieldsOffset,
|
| + methodsOffset,
|
| + members,
|
| + libraries,
|
| + libraryMap,
|
| + importCollector,
|
| + logger))
|
| : <String>[]);
|
|
|
| // Generate code for creation of getter and setter closures.
|
| @@ -630,8 +656,9 @@ class _ReflectorDomain {
|
| librariesCode = "null";
|
| } else {
|
| librariesCode = _formatAsList("m.LibraryMirror",
|
| - libraries.items.map((LibraryElement library) {
|
| - return _libraryMirrorCode(library, importCollector, logger);
|
| + libraries.items.map((_LibraryDomain library) {
|
| + return _libraryMirrorCode(library, members, topLevelVariables,
|
| + fields.length, importCollector, logger);
|
| }));
|
| }
|
|
|
| @@ -686,44 +713,34 @@ class _ReflectorDomain {
|
| return result;
|
| }
|
|
|
| - Iterable<PropertyAccessorElement> _gettersOfLibrary(LibraryElement library) {
|
| - return library.units.map((CompilationUnitElement part) {
|
| - Iterable<Element> getters = <Iterable<Element>>[
|
| - part.accessors
|
| - .where((PropertyAccessorElement accessor) => accessor.isGetter),
|
| - part.functions,
|
| - part.topLevelVariables
|
| - ].expand((Iterable<Element> elements) => elements);
|
| - return getters.where((Element getter) =>
|
| - _capabilities.supportsTopLevelInvoke(getter.name, getter.metadata));
|
| - }).expand((Iterable<Element> x) => x);
|
| - }
|
| -
|
| - Iterable<PropertyAccessorElement> _settersOfLibrary(LibraryElement library) {
|
| - return library.units.map((CompilationUnitElement part) {
|
| - Iterable setters = <Iterable<Element>>[
|
| - part.accessors
|
| - .where((PropertyAccessorElement accessor) => accessor.isSetter),
|
| - part.topLevelVariables
|
| - .where((TopLevelVariableElement variable) => !variable.isFinal)
|
| - ].expand((Iterable<Element> elements) => elements);
|
| - return setters.where((Element setter) =>
|
| - _capabilities.supportsTopLevelInvoke(setter.name, setter.metadata));
|
| - }).expand((Iterable<Element> x) => x);
|
| + Iterable<ExecutableElement> _gettersOfLibrary(_LibraryDomain library) sync* {
|
| + yield* library._accessors
|
| + .where((PropertyAccessorElement accessor) => accessor.isGetter);
|
| + yield* library._declaredFunctions;
|
| + }
|
| +
|
| + Iterable<PropertyAccessorElement> _settersOfLibrary(_LibraryDomain library) {
|
| + return library._accessors
|
| + .where((PropertyAccessorElement accessor) => accessor.isSetter);
|
| }
|
|
|
| String _classMirrorCode(
|
| _ClassDomain classDomain,
|
| Enumerator<FieldElement> fields,
|
| + int fieldsOffset,
|
| + int methodsOffset,
|
| Enumerator<ExecutableElement> members,
|
| - Enumerator<LibraryElement> libraries,
|
| + Enumerator<_LibraryDomain> libraries,
|
| + Map<LibraryElement, _LibraryDomain> libraryMap,
|
| _ImportCollector importCollector,
|
| TransformLogger logger) {
|
| + int descriptor = _classDescriptor(classDomain._classElement);
|
| +
|
| // Fields go first in [memberMirrors], so they will get the
|
| // same index as in [fields].
|
| Iterable<int> fieldsIndices =
|
| classDomain._declaredFields.map((FieldElement element) {
|
| - return fields.indexOf(element);
|
| + return fields.indexOf(element) + fieldsOffset;
|
| });
|
|
|
| // All the elements in the behavioral interface go after the
|
| @@ -742,17 +759,17 @@ class _ReflectorDomain {
|
| int index = members.indexOf(element);
|
| return index == null
|
| ? constants.NO_CAPABILITY_INDEX
|
| - : index + fields.length;
|
| + : index + methodsOffset;
|
| });
|
|
|
| - String declarationsCode = "<int>[${constants
|
| - .NO_CAPABILITY_INDEX}]";
|
| - if (_capabilities._impliesDeclarations) {
|
| - List<int> declarationsIndices = <int>[]
|
| - ..addAll(fieldsIndices)
|
| - ..addAll(methodsIndices);
|
| - declarationsCode = _formatAsList("int", declarationsIndices);
|
| - }
|
| + String declarationsCode = _capabilities._impliesDeclarations
|
| + ? _formatAsList(
|
| + "int",
|
| + () sync* {
|
| + yield* fieldsIndices;
|
| + yield* methodsIndices;
|
| + }())
|
| + : "<int>[${constants.NO_CAPABILITY_INDEX}]";
|
|
|
| // All instance members belong to the behavioral interface, so they
|
| // also get an offset of `fields.length`.
|
| @@ -764,7 +781,7 @@ class _ReflectorDomain {
|
| int index = members.indexOf(element);
|
| return index == null
|
| ? constants.NO_CAPABILITY_INDEX
|
| - : index + fields.length;
|
| + : index + methodsOffset;
|
| }));
|
|
|
| // All static members belong to the behavioral interface, so they
|
| @@ -774,7 +791,7 @@ class _ReflectorDomain {
|
| int index = members.indexOf(element);
|
| return index == null
|
| ? constants.NO_CAPABILITY_INDEX
|
| - : index + fields.length;
|
| + : index + methodsOffset;
|
| }));
|
|
|
| ClassElement classElement = classDomain._classElement;
|
| @@ -808,12 +825,11 @@ class _ReflectorDomain {
|
| staticGettersCode = _formatAsMap([
|
| classDomain._declaredMethods
|
| .where((ExecutableElement element) => element.isStatic),
|
| - classDomain._declaredAndImplicitAccessors.where(
|
| - (PropertyAccessorElement element) =>
|
| - element.isStatic && element.isGetter)
|
| + classDomain._accessors.where((PropertyAccessorElement element) =>
|
| + element.isStatic && element.isGetter)
|
| ].expand((x) => x).map((ExecutableElement element) =>
|
| _staticGettingClosure(importCollector, classElement, element.name)));
|
| - staticSettersCode = _formatAsMap(classDomain._declaredAndImplicitAccessors
|
| + staticSettersCode = _formatAsMap(classDomain._accessors
|
| .where((PropertyAccessorElement element) =>
|
| element.isStatic && element.isSetter)
|
| .map((PropertyAccessorElement element) => _staticSettingClosure(
|
| @@ -832,7 +848,7 @@ class _ReflectorDomain {
|
| if (mixinIndex == null) mixinIndex = constants.NO_CAPABILITY_INDEX;
|
|
|
| int ownerIndex = _capabilities.supportsLibraries
|
| - ? libraries.indexOf(classElement.library)
|
| + ? libraries.indexOf(libraryMap[classElement.library])
|
| : constants.NO_CAPABILITY_INDEX;
|
|
|
| String superinterfaceIndices = _formatAsList(
|
| @@ -853,7 +869,7 @@ class _ReflectorDomain {
|
| int classIndex = classes.indexOf(classElement);
|
|
|
| String result = 'new r.ClassMirrorImpl(r"${classDomain._simpleName}", '
|
| - 'r"${_qualifiedName(classElement)}", $classIndex, '
|
| + 'r"${_qualifiedName(classElement)}", $descriptor, $classIndex, '
|
| '${_constConstructionCode(importCollector)}, '
|
| '$declarationsCode, $instanceMembersCode, $staticMembersCode, '
|
| '$superclassIndex, $staticGettersCode, $staticSettersCode, '
|
| @@ -950,24 +966,55 @@ class _ReflectorDomain {
|
| if (classElement is MixinApplication && classElement.declaredName == null) {
|
| return 'new r.FakeType(r"${_qualifiedName(classElement)}")';
|
| }
|
| - if (classElement is! MixinApplication && classElement.type.isDynamic) {
|
| - return "dynamic";
|
| - }
|
| + if (classElement.type.isDynamic) return "dynamic";
|
| String prefix = importCollector._getPrefix(classElement.library);
|
| return "$prefix.${classElement.name}";
|
| }
|
|
|
| - String _libraryMirrorCode(LibraryElement library,
|
| - _ImportCollector importCollector, TransformLogger logger) {
|
| + String _libraryMirrorCode(
|
| + _LibraryDomain libraryDomain,
|
| + Enumerator<ExecutableElement> members,
|
| + Enumerator<TopLevelVariableElement> variables,
|
| + int fieldsLength,
|
| + _ImportCollector importCollector,
|
| + TransformLogger logger) {
|
| + LibraryElement library = libraryDomain._libraryElement;
|
| +
|
| String gettersCode = _formatAsMap(
|
| - _gettersOfLibrary(library).map((PropertyAccessorElement getter) {
|
| + _gettersOfLibrary(libraryDomain).map((PropertyAccessorElement getter) {
|
| return _topLevelGettingClosure(importCollector, library, getter.name);
|
| }));
|
| +
|
| String settersCode = _formatAsMap(
|
| - _settersOfLibrary(library).map((PropertyAccessorElement setter) {
|
| + _settersOfLibrary(libraryDomain).map((PropertyAccessorElement setter) {
|
| return topLevelSettingClosure(importCollector, library, setter.name);
|
| }));
|
|
|
| + // Fields go first in [memberMirrors], so they will get the
|
| + // same index as in [fields].
|
| + Iterable<int> variableIndices =
|
| + libraryDomain._declaredVariables.map((TopLevelVariableElement element) {
|
| + return variables.indexOf(element);
|
| + });
|
| +
|
| + // All the elements in the behavioral interface go after the
|
| + // fields in [memberMirrors], so they must get an offset of
|
| + // `fields.length` on the index.
|
| + Iterable<int> methodsIndices = libraryDomain._declarations
|
| + .where(_executableIsntImplicitGetterOrSetter)
|
| + .map((ExecutableElement element) {
|
| + int index = members.indexOf(element);
|
| + return index + fieldsLength;
|
| + });
|
| +
|
| + String declarationsCode = "<int>[${constants.NO_CAPABILITY_INDEX}]";
|
| + if (_capabilities._impliesDeclarations) {
|
| + List<int> declarationsIndices = <int>[]
|
| + ..addAll(variableIndices)
|
| + ..addAll(methodsIndices);
|
| + declarationsCode = _formatAsList("int", declarationsIndices);
|
| + }
|
| +
|
| // TODO(sigurdm) clarify: Find out how to get good uri's in a
|
| // transformer.
|
| // TODO(sigurdm) implement: Check for `uriCapability`.
|
| @@ -982,7 +1029,8 @@ class _ReflectorDomain {
|
| }
|
|
|
| return 'new r.LibraryMirrorImpl(r"${library.name}", $uriCode, '
|
| - '$gettersCode, $settersCode, $metadataCode)';
|
| + '${_constConstructionCode(importCollector)}, '
|
| + '$declarationsCode, $gettersCode, $settersCode, $metadataCode)';
|
| }
|
|
|
| String _parameterMirrorCode(
|
| @@ -1305,11 +1353,8 @@ String _gettingClosure(String getterName) {
|
| // Auxiliary function used by `_generateCode`.
|
| String _settingClosure(String setterName) {
|
| assert(setterName.substring(setterName.length - 1) == "=");
|
| - // The [setterName] includes the "=", remove it.
|
| String name = setterName.substring(0, setterName.length - 1);
|
| -
|
| - return 'r"$setterName": (dynamic instance, value) => '
|
| - 'instance.$name = value';
|
| + return 'r"$setterName": (dynamic instance, value) => instance.$name = value';
|
| }
|
|
|
| // Auxiliary function used by `_generateCode`.
|
| @@ -1350,34 +1395,101 @@ String topLevelSettingClosure(_ImportCollector importCollector,
|
| return 'r"$setterName": (value) => $prefix.$name = value';
|
| }
|
|
|
| +/// Information about reflectability for a given library.
|
| +class _LibraryDomain {
|
| + /// Element describing the target library.
|
| + final LibraryElement _libraryElement;
|
| +
|
| + /// Fields declared by [_libraryElement] and included for reflection support,
|
| + /// according to the reflector described by the [_reflectorDomain];
|
| + /// obtained by filtering `_libraryElement.fields`.
|
| + final Iterable<TopLevelVariableElement> _declaredVariables;
|
| +
|
| + /// Methods which are declared by [_libraryElement] and included for
|
| + /// reflection support, according to the reflector described by
|
| + /// [_reflectorDomain]; obtained by filtering `_libraryElement.functions`.
|
| + final Iterable<FunctionElement> _declaredFunctions;
|
| +
|
| + /// Formal parameters declared by one of the [_declaredFunctions].
|
| + final Iterable<ParameterElement> _declaredParameters;
|
| +
|
| + /// Getters and setters possessed by [_libraryElement] and included for
|
| + /// reflection support, according to the reflector described by
|
| + /// [_reflectorDomain]; obtained by filtering `_libraryElement.accessors`.
|
| + /// Note that it includes declared as well as synthetic accessors, implicitly
|
| + /// created as getters/setters for fields.
|
| + final Iterable<PropertyAccessorElement> _accessors;
|
| +
|
| + /// The reflector domain that holds [this] object as one of its
|
| + /// library domains.
|
| + final _ReflectorDomain _reflectorDomain;
|
| +
|
| + _LibraryDomain(
|
| + this._libraryElement,
|
| + this._declaredVariables,
|
| + this._declaredFunctions,
|
| + this._declaredParameters,
|
| + this._accessors,
|
| + this._reflectorDomain);
|
| +
|
| + String get _simpleName {
|
| + return _libraryElement.name;
|
| + }
|
| +
|
| + /// Returns the declared methods, accessors and constructors in
|
| + /// [_classElement]. Note that this includes synthetic getters and
|
| + /// setters, and omits fields; in other words, it provides the
|
| + /// behavioral point of view on the class. Also note that this is not
|
| + /// the same semantics as that of `declarations` in [ClassMirror].
|
| + Iterable<ExecutableElement> get _declarations sync* {
|
| + yield* _declaredFunctions;
|
| + yield* _accessors;
|
| + }
|
| +
|
| + String toString() {
|
| + return "LibraryDomain($_libraryElement)";
|
| + }
|
| +
|
| + bool operator ==(Object other) {
|
| + if (other is _LibraryDomain) {
|
| + return _libraryElement == other._libraryElement &&
|
| + _reflectorDomain == other._reflectorDomain;
|
| + } else {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + int get hashCode => _libraryElement.hashCode ^ _reflectorDomain.hashCode;
|
| +}
|
| +
|
| /// Information about reflectability for a given class.
|
| class _ClassDomain {
|
| /// Element describing the target class.
|
| final ClassElement _classElement;
|
|
|
| - /// Fields declared by [classElement] and included for reflection support,
|
| - /// according to the reflector described by the [reflectorDomain];
|
| - /// obtained by filtering `classElement.fields`.
|
| + /// Fields declared by [_classElement] and included for reflection support,
|
| + /// according to the reflector described by the [_reflectorDomain];
|
| + /// obtained by filtering `_classElement.fields`.
|
| final Iterable<FieldElement> _declaredFields;
|
|
|
| - /// Methods which are declared by [classElement] and included for
|
| + /// Methods which are declared by [_classElement] and included for
|
| /// reflection support, according to the reflector described by
|
| - /// [reflectorDomain]; obtained by filtering `classElement.methods`.
|
| + /// [reflectorDomain]; obtained by filtering `_classElement.methods`.
|
| final Iterable<MethodElement> _declaredMethods;
|
|
|
| /// Formal parameters declared by one of the [_declaredMethods].
|
| final Iterable<ParameterElement> _declaredParameters;
|
|
|
| - /// Getters and setters possessed by [classElement] and included for
|
| + /// Getters and setters possessed by [_classElement] and included for
|
| /// reflection support, according to the reflector described by
|
| - /// [reflectorDomain]; obtained by filtering `classElement.accessors`.
|
| + /// [reflectorDomain]; obtained by filtering `_classElement.accessors`.
|
| /// Note that it includes declared as well as synthetic accessors,
|
| /// implicitly created as getters/setters for fields.
|
| - final Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors;
|
| + final Iterable<PropertyAccessorElement> _accessors;
|
|
|
| - /// Constructors declared by [classElement] and included for reflection
|
| - /// support, according to the reflector described by [reflectorDomain];
|
| - /// obtained by filtering `classElement.constructors`.
|
| + /// Constructors declared by [_classElement] and included for reflection
|
| + /// support, according to the reflector described by [_reflectorDomain];
|
| + /// obtained by filtering `_classElement.constructors`.
|
| final Iterable<ConstructorElement> _constructors;
|
|
|
| /// The reflector domain that holds [this] object as one of its
|
| @@ -1389,7 +1501,7 @@ class _ClassDomain {
|
| this._declaredFields,
|
| this._declaredMethods,
|
| this._declaredParameters,
|
| - this._declaredAndImplicitAccessors,
|
| + this._accessors,
|
| this._constructors,
|
| this._reflectorDomain);
|
|
|
| @@ -1429,8 +1541,7 @@ class _ClassDomain {
|
| /// the same semantics as that of `declarations` in [ClassMirror].
|
| Iterable<ExecutableElement> get _declarations {
|
| // TODO(sigurdm) feature: Include type variables (if we keep them).
|
| - return [_declaredMethods, _declaredAndImplicitAccessors, _constructors]
|
| - .expand((x) => x);
|
| + return [_declaredMethods, _accessors, _constructors].expand((x) => x);
|
| }
|
|
|
| /// Finds all instance members by going through the class hierarchy.
|
| @@ -1641,7 +1752,7 @@ class _Capabilities {
|
| return true;
|
| }
|
| // Quantifying capabilities do not influence the availability
|
| - // of reflection support for top level invocation.
|
| + // of reflection support for top-level invocation.
|
| }
|
|
|
| // All options exhausted, give up.
|
| @@ -1942,7 +2053,7 @@ class TransformerImplementation {
|
| bool isOk = checkInheritance(result.value.type, focusClass.type);
|
| return isOk ? result.value.type.element : null;
|
| } else {
|
| - // Not a const top level variable, not relevant.
|
| + // Not a const top-level variable, not relevant.
|
| return null;
|
| }
|
| }
|
| @@ -2133,7 +2244,9 @@ class TransformerImplementation {
|
| for (InterfaceType mixin in type.mixins) {
|
| ClassElement mixinElement = mixin.element;
|
| ClassElement subClass = mixin == type.mixins.last ? type : null;
|
| - String name = subClass == null ? null : type.name;
|
| + String name = subClass == null
|
| + ? null
|
| + : (type.isMixinApplication ? type.name : null);
|
| MixinApplication mixinApplication = new MixinApplication(
|
| name, superclass, mixinElement, type.library, subClass);
|
| domain._classes.add(mixinApplication);
|
| @@ -2221,6 +2334,15 @@ class TransformerImplementation {
|
| addClassDomain(type, reflector);
|
| }
|
| }
|
| + for (FunctionElement function in unit.functions) {
|
| + for (ClassElement reflector in getReflectors(
|
| + _qualifiedFunctionName(function), function.metadata)) {
|
| + // We just add the library here, the function itself will be
|
| + // supported using `invoke` and `declarations` of that library
|
| + // mirror.
|
| + addLibrary(library, reflector);
|
| + }
|
| + }
|
| }
|
| }
|
|
|
| @@ -2588,6 +2710,17 @@ bool _executableIsntImplicitGetterOrSetter(ExecutableElement executable) {
|
| }
|
|
|
| /// Returns an integer encoding of the kind and attributes of the given
|
| +/// class.
|
| +int _classDescriptor(ClassElement element) {
|
| + int result = constants.clazz;
|
| + if (element.isPrivate) result |= constants.privateAttribute;
|
| + if (element.isSynthetic) result |= constants.syntheticAttribute;
|
| + if (element.isAbstract) result |= constants.abstractAttribute;
|
| + if (element.isEnum) result |= constants.enumAttribute;
|
| + return result;
|
| +}
|
| +
|
| +/// Returns an integer encoding of the kind and attributes of the given
|
| /// field.
|
| int _fieldDescriptor(FieldElement element) {
|
| int result = constants.field;
|
| @@ -2940,6 +3073,58 @@ String _extractMetadataCode(Element element, Resolver resolver,
|
| return _formatAsList("Object", metadataParts);
|
| }
|
|
|
| +/// Returns the top level variables declared in the given [libraryElement],
|
| +/// filtering them such that the returned ones are those that are supported
|
| +/// by [capabilities].
|
| +Iterable<TopLevelVariableElement> _extractDeclaredVariables(
|
| + LibraryElement libraryElement, _Capabilities capabilities) sync* {
|
| + for (CompilationUnitElement unit in libraryElement.units) {
|
| + for (TopLevelVariableElement variable in unit.topLevelVariables) {
|
| + if (variable.isPrivate || variable.isSynthetic) continue;
|
| + // TODO(eernst) clarify: Do we want to subsume variables under invoke?
|
| + if (capabilities.supportsTopLevelInvoke(
|
| + variable.name, variable.metadata)) {
|
| + yield variable;
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +/// Returns the top level functions declared in the given [libraryElement],
|
| +/// filtering them such that the returned ones are those that are supported
|
| +/// by [capabilities].
|
| +Iterable<FunctionElement> _extractDeclaredFunctions(
|
| + LibraryElement libraryElement, _Capabilities capabilities) sync* {
|
| + for (CompilationUnitElement unit in libraryElement.units) {
|
| + for (FunctionElement function in unit.functions) {
|
| + if (function.isPrivate) continue;
|
| + if (capabilities.supportsTopLevelInvoke(
|
| + function.name, function.metadata)) {
|
| + yield function;
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +/// Returns the parameters declared in the given [declaredFunctions] as well
|
| +/// as the setters from the given [accessors].
|
| +Iterable<ParameterElement> _extractDeclaredFunctionParameters(
|
| + Iterable<FunctionElement> declaredFunctions,
|
| + Iterable<ExecutableElement> accessors) {
|
| + List<ParameterElement> result = <ParameterElement>[];
|
| + for (FunctionElement declaredFunction in declaredFunctions) {
|
| + result.addAll(declaredFunction.parameters);
|
| + }
|
| + for (ExecutableElement accessor in accessors) {
|
| + if (accessor is PropertyAccessorElement && accessor.isSetter) {
|
| + result.addAll(accessor.parameters);
|
| + }
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +/// Returns the declared fields in the given [classElement], filtered such
|
| +/// that the returned ones are the ones that are supported by [capabilities].
|
| Iterable<FieldElement> _extractDeclaredFields(
|
| ClassElement classElement, _Capabilities capabilities) {
|
| return classElement.fields.where((FieldElement field) {
|
| @@ -2951,6 +3136,8 @@ Iterable<FieldElement> _extractDeclaredFields(
|
| });
|
| }
|
|
|
| +/// Returns the declared methods in the given [classElement], filtered such
|
| +/// that the returned ones are the ones that are supported by [capabilities].
|
| Iterable<MethodElement> _extractDeclaredMethods(
|
| ClassElement classElement, _Capabilities capabilities) {
|
| return classElement.methods.where((MethodElement method) {
|
| @@ -2962,6 +3149,9 @@ Iterable<MethodElement> _extractDeclaredMethods(
|
| });
|
| }
|
|
|
| +/// Returns the declared parameters in the given [declaredMethods] and
|
| +/// [declaredConstructors], as well as the ones from the setters in
|
| +/// [accessors].
|
| Iterable<ParameterElement> _extractDeclaredParameters(
|
| Iterable<MethodElement> declaredMethods,
|
| Iterable<ConstructorElement> declaredConstructors,
|
| @@ -2981,6 +3171,21 @@ Iterable<ParameterElement> _extractDeclaredParameters(
|
| return result;
|
| }
|
|
|
| +/// Returns the accessors from the given [libraryElement], filtured such that
|
| +/// the returned ones are the ones that are supported by [capabilities].
|
| +Iterable<ExecutableElement> _extractLibraryAccessors(
|
| + LibraryElement libraryElement, _Capabilities capabilities) sync* {
|
| + for (CompilationUnitElement unit in libraryElement.units) {
|
| + for (PropertyAccessorElement accessor in unit.accessors) {
|
| + if (accessor.isPrivate) continue;
|
| + if (capabilities.supportsTopLevelInvoke(
|
| + accessor.name, accessor.metadata)) {
|
| + yield accessor;
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| /// Returns the [PropertyAccessorElement]s which are the accessors
|
| /// of the given [classElement], including both the declared ones
|
| /// and the implicitly generated ones corresponding to fields. This
|
| @@ -2989,7 +3194,7 @@ Iterable<ParameterElement> _extractDeclaredParameters(
|
| /// interface, e.g., `declarations`. But the latter can be computed from
|
| /// here, by filtering out the accessors whose `isSynthetic` is true
|
| /// and adding the fields.
|
| -Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors(
|
| +Iterable<PropertyAccessorElement> _extractAccessors(
|
| ClassElement classElement, _Capabilities capabilities) {
|
| return classElement.accessors.where((PropertyAccessorElement accessor) {
|
| if (accessor.isPrivate) return false;
|
| @@ -3000,7 +3205,9 @@ Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors(
|
| });
|
| }
|
|
|
| -Iterable<ConstructorElement> _declaredConstructors(
|
| +/// Returns the declared constructors from [classElement], filtered such that
|
| +/// the returned ones are the ones that are supported by [capabilities].
|
| +Iterable<ConstructorElement> _extractDeclaredConstructors(
|
| ClassElement classElement, _Capabilities capabilities) {
|
| return classElement.constructors.where((ConstructorElement constructor) {
|
| if (constructor.isPrivate) return false;
|
| @@ -3009,6 +3216,26 @@ Iterable<ConstructorElement> _declaredConstructors(
|
| });
|
| }
|
|
|
| +_LibraryDomain _createLibraryDomain(
|
| + LibraryElement library, _ReflectorDomain domain) {
|
| + List<TopLevelVariableElement> declaredVariablesOfLibrary =
|
| + _extractDeclaredVariables(library, domain._capabilities).toList();
|
| + List<FunctionElement> declaredFunctionsOfLibrary =
|
| + _extractDeclaredFunctions(library, domain._capabilities).toList();
|
| + List<PropertyAccessorElement> accessorsOfLibrary =
|
| + _extractLibraryAccessors(library, domain._capabilities);
|
| + List<ParameterElement> declaredParametersOfLibrary =
|
| + _extractDeclaredFunctionParameters(
|
| + declaredFunctionsOfLibrary, accessorsOfLibrary);
|
| + return new _LibraryDomain(
|
| + library,
|
| + declaredVariablesOfLibrary,
|
| + declaredFunctionsOfLibrary,
|
| + declaredParametersOfLibrary,
|
| + accessorsOfLibrary,
|
| + domain);
|
| +}
|
| +
|
| _ClassDomain _createClassDomain(ClassElement type, _ReflectorDomain domain) {
|
| if (type is MixinApplication) {
|
| List<FieldElement> declaredFieldsOfClass =
|
| @@ -3020,8 +3247,7 @@ _ClassDomain _createClassDomain(ClassElement type, _ReflectorDomain domain) {
|
| .where((MethodElement e) => !e.isStatic)
|
| .toList();
|
| List<PropertyAccessorElement> declaredAndImplicitAccessorsOfClass =
|
| - _declaredAndImplicitAccessors(type.mixin, domain._capabilities)
|
| - .toList();
|
| + _extractAccessors(type.mixin, domain._capabilities).toList();
|
| List<ConstructorElement> declaredConstructorsOfClass =
|
| new List<ConstructorElement>();
|
| List<ParameterElement> declaredParametersOfClass =
|
| @@ -3043,9 +3269,9 @@ _ClassDomain _createClassDomain(ClassElement type, _ReflectorDomain domain) {
|
| List<MethodElement> declaredMethodsOfClass =
|
| _extractDeclaredMethods(type, domain._capabilities).toList();
|
| List<PropertyAccessorElement> declaredAndImplicitAccessorsOfClass =
|
| - _declaredAndImplicitAccessors(type, domain._capabilities).toList();
|
| + _extractAccessors(type, domain._capabilities).toList();
|
| List<ConstructorElement> declaredConstructorsOfClass =
|
| - _declaredConstructors(type, domain._capabilities).toList();
|
| + _extractDeclaredConstructors(type, domain._capabilities).toList();
|
| List<ParameterElement> declaredParametersOfClass = _extractDeclaredParameters(
|
| declaredMethodsOfClass,
|
| declaredConstructorsOfClass,
|
| @@ -3116,13 +3342,16 @@ class MixinApplication implements ClassElement {
|
| }
|
|
|
| @override
|
| + String get displayName => name;
|
| +
|
| + @override
|
| List<InterfaceType> get interfaces => <InterfaceType>[];
|
|
|
| @override
|
| List<ElementAnnotation> get metadata => <ElementAnnotation>[];
|
|
|
| @override
|
| - bool get isSynthetic => declaredName != null;
|
| + bool get isSynthetic => declaredName == null;
|
|
|
| // Note that the `InterfaceTypeImpl` may well call methods on this
|
| // `MixinApplication` whose body is `_unImplemented()`, but it still provides
|
| @@ -3155,6 +3384,12 @@ class MixinApplication implements ClassElement {
|
| bool get isMixinApplication => declaredName != null;
|
|
|
| @override
|
| + bool get isAbstract => !isMixinApplication || mixin.isAbstract;
|
| +
|
| + @override
|
| + bool get isEnum => false;
|
| +
|
| + @override
|
| NamedCompilationUnitMember computeNode() =>
|
| declaredName != null ? subclass.computeNode() : null;
|
|
|
| @@ -3196,12 +3431,6 @@ class MixinApplication implements ClassElement {
|
| bool get hasStaticMember => _unImplemented();
|
|
|
| @override
|
| - bool get isAbstract => _unImplemented();
|
| -
|
| - @override
|
| - bool get isEnum => _unImplemented();
|
| -
|
| - @override
|
| bool get isOrInheritsProxy => _unImplemented();
|
|
|
| @override
|
| @@ -3297,9 +3526,6 @@ class MixinApplication implements ClassElement {
|
| get context => _unImplemented();
|
|
|
| @override
|
| - String get displayName => _unImplemented();
|
| -
|
| - @override
|
| Element get enclosingElement => _unImplemented();
|
|
|
| @override
|
| @@ -3356,3 +3582,9 @@ String _qualifiedName(ClassElement classElement) {
|
| ? "null"
|
| : "${classElement.library.name}.${classElement.name}";
|
| }
|
| +
|
| +String _qualifiedFunctionName(FunctionElement functionElement) {
|
| + return functionElement == null
|
| + ? "null"
|
| + : "${functionElement.library.name}.${functionElement.name}";
|
| +}
|
|
|