| Index: reflectable/lib/src/transformer_implementation.dart | 
| diff --git a/reflectable/lib/src/transformer_implementation.dart b/reflectable/lib/src/transformer_implementation.dart | 
| index deaeb57d306f116984ae071c54abfe97ece97c4d..f4850a28926b0cdd2aab2b2aa6ecdf6e0fcc52ee 100644 | 
| --- a/reflectable/lib/src/transformer_implementation.dart | 
| +++ b/reflectable/lib/src/transformer_implementation.dart | 
| @@ -658,7 +658,6 @@ class _ReflectorDomain { | 
| parameterNode.defaultValue != null) { | 
| defaultValueCode = " = ${_extractConstantCode( | 
| parameterNode.defaultValue, | 
| -            parameterElement.library, | 
| importCollector, logger, _generatedLibraryId, _resolver)}"; | 
| } | 
| return "${parameterNames[requiredPositionalCount + i]}" | 
| @@ -679,7 +678,6 @@ class _ReflectorDomain { | 
| parameterNode.defaultValue != null) { | 
| defaultValueCode = ": ${_extractConstantCode( | 
| parameterNode.defaultValue, | 
| -            parameterElement.library, | 
| importCollector, logger, _generatedLibraryId, _resolver)}"; | 
| } | 
| return "${namedParameterNames[i]}$defaultValueCode"; | 
| @@ -787,9 +785,10 @@ class _ReflectorDomain { | 
| // [parameters], [instanceGetterNames], and [instanceSetterNames]. | 
| _libraries.items.forEach(uncheckedAddLibrary); | 
| classes.forEach((ClassElement classElement) { | 
| +      LibraryElement classLibrary = classElement.library; | 
| if (!libraries.items.any((_LibraryDomain libraryDomain) => | 
| -          libraryDomain._libraryElement == classElement.library)) { | 
| -        addLibrary(classElement.library); | 
| +          libraryDomain._libraryElement == classLibrary)) { | 
| +        addLibrary(classLibrary); | 
| } | 
| classElement.typeParameters.forEach(typeParameters.add); | 
| }); | 
| @@ -863,8 +862,9 @@ class _ReflectorDomain { | 
| if (_capabilities._impliesTypes && _capabilities._impliesTypeAnnotations) { | 
| void addClass(ClassElement classElement) { | 
| classes.add(classElement); | 
| -        if (!libraries.items.contains(classElement.library)) { | 
| -          uncheckedAddLibrary(classElement.library); | 
| +        LibraryElement classLibrary = classElement.library; | 
| +        if (!libraries.items.contains(classLibrary)) { | 
| +          uncheckedAddLibrary(classLibrary); | 
| } | 
| } | 
|  | 
| @@ -1934,13 +1934,8 @@ class _ReflectorDomain { | 
| String defaultValueCode = "null"; | 
| if (parameterNode is DefaultFormalParameter && | 
| parameterNode.defaultValue != null) { | 
| -      defaultValueCode = _extractConstantCode( | 
| -          parameterNode.defaultValue, | 
| -          element.library, | 
| -          importCollector, | 
| -          logger, | 
| -          _generatedLibraryId, | 
| -          _resolver); | 
| +      defaultValueCode = _extractConstantCode(parameterNode.defaultValue, | 
| +          importCollector, logger, _generatedLibraryId, _resolver); | 
| } | 
| String parameterSymbolCode = descriptor & constants.namedAttribute != 0 | 
| ? "#${element.name}" | 
| @@ -2556,7 +2551,8 @@ class _Capabilities { | 
| Iterable<DartObjectImpl> _getEvaluatedMetadata( | 
| Iterable<ElementAnnotation> metadata) { | 
| return metadata.map((ElementAnnotationImpl elementAnnotation) { | 
| -      EvaluationResultImpl evaluation = elementAnnotation.evaluationResult; | 
| +      EvaluationResultImpl evaluation = | 
| +          _annotationEvaluationResult(elementAnnotation); | 
| if (evaluation != null) return evaluation.value; | 
| // The `evaluationResult` from a getter is `null`, so we have to deal | 
| // with that case separately. | 
| @@ -2913,7 +2909,7 @@ class TransformerImplementation { | 
| FieldElement idField = type.getField("thisClassId"); | 
| if (idField == null || !idField.isStatic) return false; | 
| if (idField is ConstFieldElementImpl) { | 
| -      EvaluationResultImpl idResult = idField.evaluationResult; | 
| +      EvaluationResultImpl idResult = _constFieldEvaluationResult(idField); | 
| if (idResult != null) { | 
| return idField.constantValue.toStringValue() == | 
| reflectable_class_constants.id; | 
| @@ -2922,10 +2918,11 @@ class TransformerImplementation { | 
| // occur "if this variable is not a 'const' variable, if it does not | 
| // have an initializer, or if the compilation unit containing the | 
| // variable has not been resolved". The third case should not occur with | 
| -      // the approach we use to obtain a `LibraryElement`, so it is not the | 
| +      // the approach we use to obtain the `LibraryElement` for the library | 
| +      // 'package:reflectable/reflectable.dart', so it is not the | 
| // right declaration we are looking at. | 
| } | 
| -    // Not a const field, or failed the test, cannot be the right class. | 
| +    // Not a const field, or failed the `id` test: cannot be the right class. | 
| return false; | 
| } | 
|  | 
| @@ -3010,7 +3007,8 @@ class TransformerImplementation { | 
| // [VariableElementImpl], but with that one we would have to test | 
| // `isConst` as well. | 
| if (variable is ConstTopLevelVariableElementImpl) { | 
| -        EvaluationResultImpl result = variable.evaluationResult; | 
| +        EvaluationResultImpl result = | 
| +            _constTopLevelVariableEvaluationResult(variable); | 
| // Handle errors during evaluation. In general `evaluationResult` is | 
| // null for (1) non-const variables, (2) variables without an | 
| // initializer, and (3) unresolved libraries; (3) should not occur | 
| @@ -3027,7 +3025,7 @@ class TransformerImplementation { | 
| // we have non-const metadata then the program (pre- and post- | 
| // transformed) will be rejected by the analyzer and the compilers, | 
| // which means that it is unimportant for us to reject that case. | 
| -        EvaluationResultImpl result = variable.evaluationResult; | 
| +        EvaluationResultImpl result = _constFieldEvaluationResult(variable); | 
| if (result?.value == null) return null; | 
| bool isOk = checkInheritance(result.value.type, focusClass.type); | 
| return isOk ? result.value.type.element : null; | 
| @@ -3083,9 +3081,11 @@ class TransformerImplementation { | 
|  | 
| for (LibraryElement library in _resolver.libraries) { | 
| for (ImportElement import in library.imports) { | 
| +        if (import.importedLibrary != reflectableLibrary) continue; | 
| for (ElementAnnotationImpl metadatum in import.metadata) { | 
| if (metadatum.element == globalQuantifyCapabilityConstructor) { | 
| -            EvaluationResultImpl evaluation = metadatum.evaluationResult; | 
| +            EvaluationResultImpl evaluation = | 
| +                _annotationEvaluationResult(metadatum); | 
| if (evaluation != null && evaluation.value != null) { | 
| DartObjectImpl value = evaluation.value; | 
| String pattern = value.fields["classNamePattern"].toStringValue(); | 
| @@ -3116,7 +3116,8 @@ class TransformerImplementation { | 
| } | 
| } else if (metadatum.element == | 
| globalQuantifyMetaCapabilityConstructor) { | 
| -            EvaluationResultImpl evaluation = metadatum.evaluationResult; | 
| +            EvaluationResultImpl evaluation = | 
| +                _annotationEvaluationResult(metadatum); | 
| if (evaluation?.value != null) { | 
| DartObjectImpl value = evaluation.value; | 
| Object metadataFieldValue = | 
| @@ -3265,10 +3266,11 @@ class TransformerImplementation { | 
| /// it if none exists. | 
| _ReflectorDomain getReflectorDomain(ClassElement reflector) { | 
| return domains.putIfAbsent(reflector, () { | 
| +        LibraryElement reflectorLibrary = reflector.library; | 
| _Capabilities capabilities = | 
| _capabilitiesOf(capabilityLibrary, reflector); | 
| -        assert(_isImportableLibrary(reflector.library, dataId, _resolver)); | 
| -        importCollector._addLibrary(reflector.library); | 
| +        assert(_isImportableLibrary(reflectorLibrary, dataId, _resolver)); | 
| +        importCollector._addLibrary(reflectorLibrary); | 
| return new _ReflectorDomain(_resolver, dataId, reflector, capabilities); | 
| }); | 
| } | 
| @@ -3326,11 +3328,11 @@ class TransformerImplementation { | 
| } | 
| } | 
|  | 
| -    /// Runs through a list of metadata, and finds any Reflectors, and | 
| +    /// Runs through [metadata] and finds all reflectors as well as | 
| /// objects that are associated with reflectors via | 
| -    /// GlobalQuantifyMetaCapability and GlobalQuantifyCapability. | 
| +    /// [GlobalQuantifyMetaCapability] or [GlobalQuantifyCapability]. | 
| /// [qualifiedName] is the name of the library or class annotated by | 
| -    /// metadata. | 
| +    /// [metadata]. | 
| Iterable<ClassElement> getReflectors( | 
| String qualifiedName, List<ElementAnnotation> metadata) { | 
| List<ClassElement> result = <ClassElement>[]; | 
| @@ -3770,6 +3772,7 @@ _initializeReflectable() { | 
| } | 
| return; | 
| } | 
| +    reflectableLibrary = _resolvedLibraryOf(reflectableLibrary); | 
|  | 
| LibraryElement entryPointLibrary = _resolver.getLibrary(asset.id); | 
| if (const bool.fromEnvironment("reflectable.print.entry.point")) { | 
| @@ -3811,6 +3814,10 @@ _initializeReflectable() { | 
| if (const bool.fromEnvironment("reflectable.pause.at.exit")) { | 
| _processedEntryPointCount++; | 
| } | 
| +    if (const bool.fromEnvironment("reflectable.print.resolved.libraries")) { | 
| +      print("Resolved libraries for $currentEntryPoint: " | 
| +          "${_resolvedLibraries.length}/${_resolver.libraries.length}"); | 
| +    } | 
| _resolver.release(); | 
|  | 
| if (const bool.fromEnvironment("reflectable.pause.at.exit")) { | 
| @@ -4006,7 +4013,6 @@ String _formatAsMap(Iterable parts) => "{${parts.join(", ")}}"; | 
| /// would evaluate to in [originatingLibrary]. | 
| String _extractConstantCode( | 
| Expression expression, | 
| -    LibraryElement originatingLibrary, | 
| _ImportCollector importCollector, | 
| TransformLogger logger, | 
| AssetId generatedLibraryId, | 
| @@ -4038,8 +4044,7 @@ String _extractConstantCode( | 
| if (_isImportableLibrary( | 
| libraryOfConstructor, generatedLibraryId, resolver)) { | 
| importCollector._addLibrary(libraryOfConstructor); | 
| -        String prefix = | 
| -            importCollector._getPrefix(expression.staticElement.library); | 
| +        String prefix = importCollector._getPrefix(libraryOfConstructor); | 
| // TODO(sigurdm) implement: Named arguments. | 
| String arguments = | 
| expression.argumentList.arguments.map((Expression argument) { | 
| @@ -4115,13 +4120,8 @@ String _extractConstantCode( | 
| String b = helper(arguments[1]); | 
| return "identical($a, $b)"; | 
| } else if (expression is NamedExpression) { | 
| -      String value = _extractConstantCode( | 
| -          expression.expression, | 
| -          originatingLibrary, | 
| -          importCollector, | 
| -          logger, | 
| -          generatedLibraryId, | 
| -          resolver); | 
| +      String value = _extractConstantCode(expression.expression, | 
| +          importCollector, logger, generatedLibraryId, resolver); | 
| return "${expression.name} $value"; | 
| } else { | 
| assert(expression is IntegerLiteral || | 
| @@ -4134,6 +4134,7 @@ String _extractConstantCode( | 
| return expression.toSource(); | 
| } | 
| } | 
| + | 
| return helper(expression); | 
| } | 
|  | 
| @@ -4226,7 +4227,6 @@ String _extractMetadataCode(Element element, Resolver resolver, | 
| continue; | 
| } | 
|  | 
| -    LibraryElement library = annotationNode.element.library; | 
| if (!_isImportable(annotationNode.element, dataId, resolver)) { | 
| // Private constants, and constants made of classes in internal libraries | 
| // cannot be represented. | 
| @@ -4238,8 +4238,9 @@ String _extractMetadataCode(Element element, Resolver resolver, | 
| span: resolver.getSourceSpan(element)); | 
| continue; | 
| } | 
| -    importCollector._addLibrary(library); | 
| -    String prefix = importCollector._getPrefix(library); | 
| +    LibraryElement annotationLibrary = annotationNode.element.library; | 
| +    importCollector._addLibrary(annotationLibrary); | 
| +    String prefix = importCollector._getPrefix(annotationLibrary); | 
| if (annotationNode.arguments != null) { | 
| // A const constructor. | 
| Identifier annotationName = annotationNode.name; | 
| @@ -4266,8 +4267,8 @@ String _extractMetadataCode(Element element, Resolver resolver, | 
| } | 
| String arguments = | 
| annotationNode.arguments.arguments.map((Expression argument) { | 
| -        return _extractConstantCode(argument, element.library, importCollector, | 
| -            logger, dataId, resolver); | 
| +        return _extractConstantCode( | 
| +            argument, importCollector, logger, dataId, resolver); | 
| }).join(", "); | 
| if (_isPrivateName(name)) { | 
| logger.error("Cannot access private name $name"); | 
| @@ -4659,6 +4660,12 @@ class MixinApplication implements ClassElement { | 
| declaredName != null ? subclass.computeNode() : null; | 
|  | 
| @override | 
| +  ElementKind get kind => ElementKind.CLASS; | 
| + | 
| +  @override | 
| +  ElementLocation get location => null; | 
| + | 
| +  @override | 
| bool operator ==(Object object) { | 
| return object is MixinApplication && | 
| superclass == object.superclass && | 
| @@ -4801,18 +4808,17 @@ class MixinApplication implements ClassElement { | 
| bool get isPublic => throw unreachableError("isPublic"); | 
|  | 
| @override | 
| -  ElementKind get kind => throw unreachableError("kind"); | 
| - | 
| -  @override | 
| -  ElementLocation get location => throw unreachableError("location"); | 
| - | 
| -  @override | 
| int get nameOffset => throw unreachableError("nameOffset"); | 
|  | 
| @override | 
| get source => throw unreachableError("source"); | 
|  | 
| @override | 
| +  String get documentationComment => | 
| +      throw unreachableError("documentationComment"); | 
| + | 
| +  @override | 
| +  @deprecated | 
| get docRange => throw unreachableError("docRange"); | 
|  | 
| @override | 
| @@ -4822,6 +4828,7 @@ class MixinApplication implements ClassElement { | 
| accept(ElementVisitor visitor) => throw unreachableError("accept"); | 
|  | 
| @override | 
| +  @deprecated | 
| String computeDocumentationComment() => | 
| throw unreachableError("computeDocumentationComment"); | 
|  | 
| @@ -4869,3 +4876,57 @@ String _qualifiedTypeParameterName(TypeParameterElement typeParameterElement) { | 
| bool _isPrivateName(String name) { | 
| return name.startsWith("_") || name.contains("._"); | 
| } | 
| + | 
| +/// Returns the `evaluationResult` for [annotation], after having forced | 
| +/// constant resolution to take place in `annotation.compilationUnit.library`. | 
| +/// Note that future invocations of `annotation.compilationUnit.library` will | 
| +/// return a resolved library, but previously obtained results from that method | 
| +/// will remain unresolved if they were unresolved when they were obtained. | 
| +EvaluationResultImpl _annotationEvaluationResult( | 
| +    ElementAnnotationImpl annotation) { | 
| +  _resolvedLibraryOf(annotation.compilationUnit.library); | 
| +  return annotation.evaluationResult; | 
| +} | 
| + | 
| +/// Returns the `evaluationResult` for [constFieldElement], after having forced | 
| +/// constant resolution to take place in `constFieldElement.library`. | 
| +/// Note that future invocations of `constFieldElement.library` will | 
| +/// return a resolved library, but previously obtained results from that method | 
| +/// will remain unresolved if they were unresolved when they were obtained. | 
| +EvaluationResultImpl _constFieldEvaluationResult( | 
| +    ConstFieldElementImpl constFieldElement) { | 
| +  // This is safe: The result returned from `library` will not be used again. | 
| +  _resolvedLibraryOf(constFieldElement.library); | 
| +  return constFieldElement.evaluationResult; | 
| +} | 
| + | 
| +/// Returns the `evaluationResult` for [constTopLevelVariable], after having | 
| +/// forced constant resolution to take place in `constTopLevelvariable.library`. | 
| +/// Note that future invocations of `constTopLevelVariable.library` will | 
| +/// return a resolved library, but previously obtained results from that method | 
| +/// will remain unresolved if they were unresolved when they were obtained. | 
| +EvaluationResultImpl _constTopLevelVariableEvaluationResult( | 
| +    ConstTopLevelVariableElementImpl constTopLevelVariable) { | 
| +  // This is safe: The result returned from `library` will not be used again. | 
| +  _resolvedLibraryOf(constTopLevelVariable.library); | 
| +  return constTopLevelVariable.evaluationResult; | 
| +} | 
| + | 
| +/// Requests resolution of constants in [libraryElement] and returns a | 
| +/// [LibraryElement] wherein they have been resolved. If the library has | 
| +/// been obtained by evaluating `library` on an `Element` and all further | 
| +/// usage of that library will happen by invoking `library` again then it is | 
| +/// safe to ignore the returned value (because the future invocations of | 
| +/// `library` will return the resolved library). | 
| +LibraryElement _resolvedLibraryOf(LibraryElement libraryElement) { | 
| +  LibraryElement resolvedLibrary = _resolvedLibraries[libraryElement]; | 
| +  if (resolvedLibrary == null) { | 
| +    resolvedLibrary = libraryElement.context | 
| +        .computeLibraryElement(libraryElement.definingCompilationUnit.source); | 
| +    _resolvedLibraries[libraryElement] = resolvedLibrary; | 
| +  } | 
| +  return resolvedLibrary; | 
| +} | 
| + | 
| +Map<LibraryElement, LibraryElement> _resolvedLibraries = | 
| +    <LibraryElement, LibraryElement>{}; | 
|  |