Version 2.10.0-48.0.dev

Merge commit '1e2772d10662d5d060666a522e6af81dc8af2e04' into 'dev'
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 3030d6d..21485aa 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -465,6 +465,7 @@
   FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS,
   FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS,
   FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_WITH,
+  HintCode.ASSIGNMENT_OF_DO_NOT_STORE,
   HintCode.CAN_BE_NULL_AFTER_NULL_AWARE,
   HintCode.DEAD_CODE,
   HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH,
diff --git a/pkg/analyzer/lib/src/dart/ast/extensions.dart b/pkg/analyzer/lib/src/dart/ast/extensions.dart
index fd66ae4..0854bf3 100644
--- a/pkg/analyzer/lib/src/dart/ast/extensions.dart
+++ b/pkg/analyzer/lib/src/dart/ast/extensions.dart
@@ -3,8 +3,29 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 
+extension ElementExtension on Element {
+  /// Return `true` if this element, the enclosing class (if there is one), or
+  /// the enclosing library, has been annotated with the `@doNotStore`
+  /// annotation.
+  bool get hasOrInheritsDoNotStore {
+    if (hasDoNotStore) {
+      return true;
+    }
+    var ancestor = enclosingElement;
+    if (ancestor is ClassElement || ancestor is ExtensionElement) {
+      if (ancestor.hasDoNotStore) {
+        return true;
+      }
+      ancestor = ancestor.enclosingElement;
+    }
+    return ancestor is CompilationUnitElement &&
+        ancestor.enclosingElement.hasDoNotStore;
+  }
+}
+
 extension ListOfFormalParameterExtension on List<FormalParameter> {
   Iterable<FormalParameterImpl> get asImpl {
     return cast<FormalParameterImpl>();
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index b9ce65f..212ad92 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -15,6 +15,14 @@
  */
 class HintCode extends AnalyzerErrorCode {
   /**
+   * Users should not assign values marked `@doNotStore`.
+   */
+  static const HintCode ASSIGNMENT_OF_DO_NOT_STORE = HintCode(
+      'ASSIGNMENT_OF_DO_NOT_STORE',
+      "'{0}' is marked 'doNotStore' and shouldn't be assigned to a field.",
+      correction: "Try removing the assignment.");
+
+  /**
    * When the target expression uses '?.' operator, it can be `null`, so all the
    * subsequent invocations should also use '?.' operator.
    */
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 6eff16b..f010244 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -13,6 +13,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/member.dart' show ExecutableMember;
@@ -335,6 +336,37 @@
               field.name,
               [field.name, overriddenElement.enclosingElement.name]);
         }
+
+        var expression = field.initializer;
+
+        Element element;
+        if (expression is PropertyAccess) {
+          element = expression.propertyName.staticElement;
+          // Tear-off.
+          if (element is FunctionElement || element is MethodElement) {
+            element = null;
+          }
+        } else if (expression is MethodInvocation) {
+          element = expression.methodName.staticElement;
+        } else if (expression is Identifier) {
+          element = expression.staticElement;
+          // Tear-off.
+          if (element is FunctionElement || element is MethodElement) {
+            element = null;
+          }
+        }
+        if (element != null) {
+          if (element.isSynthetic) {
+            element = (element as PropertyAccessorElement).variable;
+          }
+          if (element.hasOrInheritsDoNotStore) {
+            _errorReporter.reportErrorForNode(
+              HintCode.ASSIGNMENT_OF_DO_NOT_STORE,
+              expression,
+              [element.name],
+            );
+          }
+        }
       }
     } finally {
       _inDeprecatedMember = wasInDeprecatedMember;
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index cf378e9..82bacc5 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -147,12 +147,12 @@
 
   @override
   void visitClassDeclaration(ClassDeclaration node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   @override
   void visitClassTypeAlias(ClassTypeAlias node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   @override
@@ -251,7 +251,7 @@
           }
         }
       }
-      resolveMetadata(node);
+      _resolveAnnotations(node.metadata);
     }
   }
 
@@ -303,17 +303,17 @@
 
   @override
   void visitDeclaredIdentifier(DeclaredIdentifier node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   @override
   void visitEnumDeclaration(EnumDeclaration node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   @override
@@ -324,11 +324,21 @@
       // TODO(brianwilkerson) Figure out whether the element can ever be
       // something other than an ExportElement
       _resolveCombinators(exportElement.exportedLibrary, node.combinators);
-      resolveMetadata(node);
+      _resolveAnnotations(node.metadata);
     }
   }
 
   @override
+  void visitExtensionDeclaration(ExtensionDeclaration node) {
+    _resolveAnnotations(node.metadata);
+  }
+
+  @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    _resolveAnnotations(node.metadata);
+  }
+
+  @override
   void visitFieldFormalParameter(FieldFormalParameter node) {
     _resolveMetadataForParameter(node);
     super.visitFieldFormalParameter(node);
@@ -336,12 +346,12 @@
 
   @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   @override
@@ -351,8 +361,7 @@
 
   @override
   void visitGenericTypeAlias(GenericTypeAlias node) {
-    resolveMetadata(node);
-    return null;
+    _resolveAnnotations(node.metadata);
   }
 
   @override
@@ -377,7 +386,7 @@
       if (library != null) {
         _resolveCombinators(library, node.combinators);
       }
-      resolveMetadata(node);
+      _resolveAnnotations(node.metadata);
     }
   }
 
@@ -452,12 +461,12 @@
 
   @override
   void visitLibraryDirective(LibraryDirective node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   @override
@@ -467,12 +476,12 @@
 
   @override
   void visitMixinDeclaration(MixinDeclaration node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   @override
   void visitPartDirective(PartDirective node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   @override
@@ -822,13 +831,18 @@
   }
 
   @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    _resolveAnnotations(node.metadata);
+  }
+
+  @override
   void visitTypeParameter(TypeParameter node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   @override
   void visitVariableDeclaration(VariableDeclaration node) {
-    resolveMetadata(node);
+    _resolveAnnotations(node.metadata);
   }
 
   /// If the [element] is not static, report the error on the [identifier].
@@ -1616,24 +1630,6 @@
     return null;
   }
 
-  /// Given a [node] that can have annotations associated with it, resolve the
-  /// annotations in the element model representing the annotations on the node.
-  static void resolveMetadata(AnnotatedNode node) {
-    _resolveAnnotations(node.metadata);
-    if (node is VariableDeclaration) {
-      AstNode parent = node.parent;
-      if (parent is VariableDeclarationList) {
-        _resolveAnnotations(parent.metadata);
-        AstNode grandParent = parent.parent;
-        if (grandParent is FieldDeclaration) {
-          _resolveAnnotations(grandParent.metadata);
-        } else if (grandParent is TopLevelVariableDeclaration) {
-          _resolveAnnotations(grandParent.metadata);
-        }
-      }
-    }
-  }
-
   /// Return `true` if the given [identifier] is the return type of a
   /// constructor declaration.
   static bool _isConstructorReturnType(SimpleIdentifier identifier) {
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index eb1672e..5966e9e 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1085,17 +1085,6 @@
 
   @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
-    //
-    // Resolve the metadata in the library scope
-    // and associate the annotations with the element.
-    //
-    if (node.metadata != null) {
-      node.metadata.accept(this);
-      ElementResolver.resolveMetadata(node);
-    }
-    //
-    // Continue the extension resolution.
-    //
     try {
       _thisType = node.declaredElement.extendedType;
       super.visitExtensionDeclaration(node);
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_packages.dart b/pkg/analyzer/lib/src/test_utilities/mock_packages.dart
index 28eeeae..88d5bc0 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_packages.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_packages.dart
@@ -25,6 +25,7 @@
 library meta;
 
 const _AlwaysThrows alwaysThrows = const _AlwaysThrows();
+const _DoNotStore doNotStore = _DoNotStore();
 const _Factory factory = const _Factory();
 const Immutable immutable = const Immutable();
 const _Literal literal = const _Literal();
@@ -36,16 +37,19 @@
 const _Sealed sealed = const _Sealed();
 const _VisibleForTesting visibleForTesting = const _VisibleForTesting();
 
-class Immutable {
-  final String reason;
-  const Immutable([this.reason]);
-}
 class _AlwaysThrows {
   const _AlwaysThrows();
 }
+class _DoNotStore {
+  const _DoNotStore();
+}
 class _Factory {
   const _Factory();
 }
+class Immutable {
+  final String reason;
+  const Immutable([this.reason]);
+}
 class _Literal {
   const _Literal();
 }
diff --git a/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart b/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart
new file mode 100644
index 0000000..18d1264
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart
@@ -0,0 +1,166 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AssignmentOfDoNotStoreTest);
+  });
+}
+
+@reflectiveTest
+class AssignmentOfDoNotStoreTest extends PubPackageResolutionTest {
+  @override
+  void setUp() {
+    super.setUp();
+    writeTestPackageConfigWithMeta();
+  }
+
+  test_classMemberGetter() async {
+    await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+
+class A {
+  @doNotStore
+  String get v => '';
+}
+
+class B {
+  String f = A().v;
+}
+''', [
+      error(HintCode.ASSIGNMENT_OF_DO_NOT_STORE, 106, 5),
+    ]);
+  }
+
+  test_classMemberVariable() async {
+    await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+
+class A{
+  @doNotStore
+  final f = '';
+}
+
+class B {
+  String f = A().f;
+}
+''', [
+      error(HintCode.ASSIGNMENT_OF_DO_NOT_STORE, 99, 5),
+    ]);
+  }
+
+  test_classStaticGetter() async {
+    await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+
+class A {
+  @doNotStore
+  static String get v => '';
+}
+
+class B {
+  String f = A.v;
+}
+''', [
+      error(HintCode.ASSIGNMENT_OF_DO_NOT_STORE, 113, 3),
+    ]);
+  }
+
+  test_classStaticVariable() async {
+    await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+
+class A{
+  @doNotStore
+  static final f = '';
+}
+
+class B {
+  String f = A.f;
+}
+''', [
+      error(HintCode.ASSIGNMENT_OF_DO_NOT_STORE, 106, 3),
+    ]);
+  }
+
+  test_functionAssignment() async {
+    await assertNoErrorsInCode('''
+import 'package:meta/meta.dart';
+
+@doNotStore
+String g(int i) => '';
+
+class C {
+  String Function(int) f = g;
+}
+''');
+  }
+
+  test_functionReturnValue() async {
+    await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+
+@doNotStore
+String getV() => '';
+
+class A {
+  final f = getV();
+}
+''', [
+      error(HintCode.ASSIGNMENT_OF_DO_NOT_STORE, 90, 6),
+    ]);
+  }
+
+  test_methodReturnValue() async {
+    await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+
+class A {
+  @doNotStore
+  String getV() => '';
+}
+
+class B {
+  final f = A().getV();
+}
+''', [
+      error(HintCode.ASSIGNMENT_OF_DO_NOT_STORE, 106, 10),
+    ]);
+  }
+
+  test_topLevelGetter() async {
+    await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+
+@doNotStore
+String get v => '';
+
+class A {
+  final f = v;
+}
+''', [
+      error(HintCode.ASSIGNMENT_OF_DO_NOT_STORE, 89, 1),
+    ]);
+  }
+
+  test_topLevelVariable() async {
+    await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+
+@doNotStore
+final v = '';
+
+class A {
+  final f = v;
+}
+''', [
+      error(HintCode.ASSIGNMENT_OF_DO_NOT_STORE, 83, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart b/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart
index 4833c25..1a4ba96 100644
--- a/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart
@@ -750,6 +750,19 @@
       error(HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE, 63, 7),
     ]);
   }
+
+  test_topLevelVariable() async {
+    await assertErrorsInCode(r'''
+@deprecated
+int x = 1;
+
+int f() {
+  return x;
+}
+''', [
+      error(HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE, 43, 1),
+    ]);
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 9d1aa5b..5495e4e 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -22,6 +22,7 @@
 import 'argument_type_not_assignable_test.dart' as argument_type_not_assignable;
 import 'assert_in_redirecting_constructor_test.dart'
     as assert_in_redirecting_constructor;
+import 'assignment_of_do_not_store_test.dart' as assignment_of_do_not_store;
 import 'assignment_to_const_test.dart' as assignment_to_const;
 import 'assignment_to_final_local_test.dart' as assignment_to_final_local;
 import 'assignment_to_final_no_setter_test.dart'
@@ -652,6 +653,7 @@
     annotation_with_non_class.main();
     argument_type_not_assignable.main();
     assert_in_redirecting_constructor.main();
+    assignment_of_do_not_store.main();
     assignment_to_const.main();
     assignment_to_final_local.main();
     assignment_to_final_no_setter.main();
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index b1aaa3b..1ab31fc 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -24,9 +24,9 @@
   final Sorter _sorter;
 
   final Set<ClassEntity> neededClasses = {};
+  final Set<ClassEntity> neededClassTypes = {};
   final Set<ClassEntity> classesOnlyNeededForRti = {};
-  // This field is set in [computeNeededDeclarations].
-  Set<ClassEntity> classesOnlyNeededForConstructor;
+  final Set<ClassEntity> classesOnlyNeededForConstructor = {};
   final Map<OutputUnit, List<ClassEntity>> outputClassLists = {};
   final Map<OutputUnit, List<ClassEntity>> outputClassTypeLists = {};
   final Map<OutputUnit, List<ConstantValue>> outputConstantLists = {};
@@ -150,6 +150,18 @@
     Set<ClassEntity> backendTypeHelpers =
         getBackendTypeHelpers(_commonElements).toSet();
 
+    /// A class type is 'shadowed' if the class is needed for direct
+    /// instantiation in one OutputUnit while its type is needed in another
+    /// OutputUnit.
+    bool isClassTypeShadowed(ClassEntity cls) {
+      return !backendTypeHelpers.contains(cls) &&
+          _rtiNeededClasses.contains(cls) &&
+          !classesOnlyNeededForRti.contains(cls) &&
+          _options.deferClassTypes &&
+          _outputUnitData.outputUnitForClass(cls) !=
+              _outputUnitData.outputUnitForClassType(cls);
+    }
+
     // Compute needed classes.
     Set<ClassEntity> instantiatedClasses =
         // TODO(johnniwinther): This should be accessed from a codegen closed
@@ -177,10 +189,11 @@
     neededClasses.addAll(mixinClasses);
 
     // 3. Add classes only needed for their constructors.
-    classesOnlyNeededForConstructor = _codegenWorld.constructorReferences
-        .where((cls) => !neededClasses.contains(cls))
-        .toSet();
-    neededClasses.addAll(classesOnlyNeededForConstructor);
+    for (var cls in _codegenWorld.constructorReferences) {
+      if (neededClasses.add(cls)) {
+        classesOnlyNeededForConstructor.add(cls);
+      }
+    }
 
     // 4. Find all classes needed for rti.
     // It is important that this is the penultimate step, at this point,
@@ -193,21 +206,16 @@
       if (backendTypeHelpers.contains(cls)) continue;
       while (cls != null && !neededClasses.contains(cls)) {
         if (!classesOnlyNeededForRti.add(cls)) break;
+        // TODO(joshualitt) delete classesOnlyNeededForRti when the
+        // no-defer-class_types flag is removed.
+        neededClassTypes.add(cls);
         cls = _elementEnvironment.getSuperClass(cls);
       }
     }
 
-    neededClasses.addAll(classesOnlyNeededForRti);
-
-    // 5. Finally, sort the classes.
-    List<ClassEntity> sortedClasses = _sorter.sortClasses(neededClasses);
-
-    for (ClassEntity cls in sortedClasses) {
-      if (classesOnlyNeededForRti.contains(cls)) {
-        _outputListsForClassType
-            .putIfAbsent(_outputUnitData.outputUnitForClassType(cls), () => [])
-            .add(cls);
-      } else if (_nativeData.isNativeOrExtendsNative(cls) &&
+    // 5. Sort classes and add them to their respective OutputUnits.
+    for (ClassEntity cls in _sorter.sortClasses(neededClasses)) {
+      if (_nativeData.isNativeOrExtendsNative(cls) &&
           !classesOnlyNeededForConstructor.contains(cls)) {
         // For now, native classes and related classes cannot be deferred.
         nativeClassesAndSubclasses.add(cls);
@@ -221,6 +229,21 @@
             .add(cls);
       }
     }
+
+    // 6. Collect any class types 'shadowed' by direct instantiation.
+    for (ClassEntity cls in _rtiNeededClasses) {
+      if (isClassTypeShadowed(cls)) {
+        neededClassTypes.add(cls);
+      }
+    }
+
+    // 7. Sort classes needed for type checking and then add them to their
+    // respective OutputUnits.
+    for (ClassEntity cls in _sorter.sortClasses(neededClassTypes)) {
+      _outputListsForClassType
+          .putIfAbsent(_outputUnitData.outputUnitForClassType(cls), () => [])
+          .add(cls);
+    }
   }
 
   void computeNeededStatics() {
@@ -292,9 +315,12 @@
       outputLibraryLists.putIfAbsent(unit, () => {}).add(library);
     });
     neededClasses.forEach((ClassEntity element) {
-      OutputUnit unit = classesOnlyNeededForRti.contains(element)
-          ? _outputUnitData.outputUnitForClassType(element)
-          : _outputUnitData.outputUnitForClass(element);
+      OutputUnit unit = _outputUnitData.outputUnitForClass(element);
+      LibraryEntity library = element.library;
+      outputLibraryLists.putIfAbsent(unit, () => {}).add(library);
+    });
+    neededClassTypes.forEach((ClassEntity element) {
+      OutputUnit unit = _outputUnitData.outputUnitForClassType(element);
       LibraryEntity library = element.library;
       outputLibraryLists.putIfAbsent(unit, () => {}).add(library);
     });
diff --git a/tools/VERSION b/tools/VERSION
index 8f56a69..56495e1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 47
+PRERELEASE 48
 PRERELEASE_PATCH 0
\ No newline at end of file