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