Version 2.13.0-4.0.dev

Merge commit 'b66bab009c5c2e96cd8465ecef805c7dacf94194' into 'dev'
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index f5f74d3..d7aa0c8 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -219,8 +219,22 @@
     });
   }
 
-  void ensureClassMembers(ir.Class node) {
-    classes.getEnv(getClassInternal(node)).ensureMembers(this);
+  /// Returns the [ClassEntity] for [node] while ensuring that the member
+  /// environment for [node] is computed.
+  ///
+  /// This is needed to ensure that live members are always included in the
+  /// environment of a class. Static members and mixed in members a member
+  /// can be become live through static access and mixin application,
+  /// respectively, which does not require lookup into the class members.
+  ///
+  /// Since the J-model class environment is computed from the K-model
+  /// environment, not ensuring the computation of the class members, can result
+  /// in a live member being present in the J-model but unavailable when queried
+  /// as a member of its enclosing class.
+  ClassEntity getClassForMemberInternal(ir.Class node) {
+    ClassEntity cls = getClassInternal(node);
+    classes.getEnv(cls).ensureMembers(this);
+    return cls;
   }
 
   MemberEntity lookupClassMember(IndexedClass cls, String name,
@@ -1234,7 +1248,7 @@
         "Environment of $this is closed. Trying to create "
         "constructor for $node.");
     ir.FunctionNode functionNode;
-    ClassEntity enclosingClass = getClassInternal(node.enclosingClass);
+    ClassEntity enclosingClass = getClassForMemberInternal(node.enclosingClass);
     Name name = getName(node.name);
     bool isExternal = node.isExternal;
 
@@ -1281,7 +1295,7 @@
     LibraryEntity library;
     ClassEntity enclosingClass;
     if (node.enclosingClass != null) {
-      enclosingClass = getClassInternal(node.enclosingClass);
+      enclosingClass = getClassForMemberInternal(node.enclosingClass);
       library = enclosingClass.library;
     } else {
       library = getLibraryInternal(node.enclosingLibrary);
@@ -1333,7 +1347,7 @@
     LibraryEntity library;
     ClassEntity enclosingClass;
     if (node.enclosingClass != null) {
-      enclosingClass = getClassInternal(node.enclosingClass);
+      enclosingClass = getClassForMemberInternal(node.enclosingClass);
       library = enclosingClass.library;
     } else {
       library = getLibraryInternal(node.enclosingLibrary);
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index 49c87e2..4393f84 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -275,6 +275,12 @@
   /// the members in [liveMembers].
   JClassEnv convert(IrToElementMap elementMap,
       Map<MemberEntity, MemberUsage> liveMemberUsage);
+
+  /// Returns `true` if [node] is a known member of this class.
+  ///
+  /// This method is used for checking the integrity of the K-model and does
+  /// not alter the state of this class environment.
+  bool checkHasMember(ir.Member node);
 }
 
 int orderByFileOffset(ir.TreeNode a, ir.TreeNode b) {
@@ -316,6 +322,14 @@
   }
 
   @override
+  bool checkHasMember(ir.Member node) {
+    if (_memberMap == null) return false;
+    return _memberMap.values.contains(node) ||
+        _setterMap.values.contains(node) ||
+        _constructorMap.values.contains(node);
+  }
+
+  @override
   void ensureMembers(KernelToElementMapImpl elementMap) {
     _ensureMaps(elementMap);
   }
diff --git a/pkg/compiler/lib/src/kernel/kernel_world.dart b/pkg/compiler/lib/src/kernel/kernel_world.dart
index 09475e4..2f25c0c 100644
--- a/pkg/compiler/lib/src/kernel/kernel_world.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_world.dart
@@ -2,6 +2,7 @@
 // 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 '../common.dart';
 import '../common/names.dart';
 import '../common_elements.dart';
 import '../elements/entities.dart';
@@ -135,6 +136,23 @@
       this.instantiatedTypes})
       : _implementedClasses = implementedClasses {
     _rtiNeed = rtiNeedBuilder.computeRuntimeTypesNeed(this, options);
+    assert(_checkIntegrity());
+  }
+
+  bool _checkIntegrity() {
+    for (MemberEntity member in liveMemberUsage.keys) {
+      if (member.enclosingClass != null) {
+        if (!elementMap.classes
+            .getEnv(member.enclosingClass)
+            .checkHasMember(elementMap.getMemberNode(member))) {
+          throw new SpannableAssertionFailure(
+              member,
+              "Member $member is in the environment of its enclosing class"
+              " ${member.enclosingClass}.");
+        }
+      }
+    }
+    return true;
   }
 
   @override
diff --git a/pkg/compiler/lib/src/kernel/native_basic_data.dart b/pkg/compiler/lib/src/kernel/native_basic_data.dart
index d030007..fc85b5e 100644
--- a/pkg/compiler/lib/src/kernel/native_basic_data.dart
+++ b/pkg/compiler/lib/src/kernel/native_basic_data.dart
@@ -139,11 +139,6 @@
                 constructor, memberName);
           }
         });
-      } else {
-        // TODO(44754): For now, this call is required to correctly load
-        // the environment for some of the tests in the _2 directories.
-        elementEnvironment.forEachConstructor(
-            cls, (ConstructorEntity constructor) {});
       }
     });
 
diff --git a/pkg/compiler/test/model/cfe_annotations_test.dart b/pkg/compiler/test/model/cfe_annotations_test.dart
index 2b5a8f8..c9bd48e 100644
--- a/pkg/compiler/test/model/cfe_annotations_test.dart
+++ b/pkg/compiler/test/model/cfe_annotations_test.dart
@@ -449,6 +449,11 @@
 
       testAll(compiler.frontendClosedWorldForTesting.nativeData);
       if (useIr) {
+        // We need to open the environment because creating annotation data
+        // from IR will create K-model classes and members for all annotations
+        // in the IR component, and not just the ones queried specifically for
+        // JS-interop and pragma-like annotations.
+        elementMap.envIsClosed = false;
         testAll(new NativeDataImpl.fromIr(elementMap, annotationData));
       }
     }
diff --git a/tools/VERSION b/tools/VERSION
index 9a6e00b..9ff967c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 3
+PRERELEASE 4
 PRERELEASE_PATCH 0
\ No newline at end of file