Version 2.19.0-47.0.dev
Merge commit '9a33b2a51d227021ae25a55cd10b675e07e19ccd' into 'dev'
diff --git a/DEPS b/DEPS
index 1ad3427..6756097 100644
--- a/DEPS
+++ b/DEPS
@@ -58,7 +58,7 @@
# Checkout extra javascript engines for testing or benchmarking.
# d8, the V8 shell, is always checked out.
"checkout_javascript_engines": False,
- "d8_tag": "version:10.5.100",
+ "d8_tag": "version:10.5.128",
"jsshell_tag": "version:95.0",
# As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
@@ -108,8 +108,8 @@
# For more details, see https://github.com/dart-lang/sdk/issues/30164.
"dart_style_rev": "d7b73536a8079331c888b7da539b80e6825270ea", # manually rev'd
- "dartdoc_rev": "d3b0b724972ffcc70a47c35a31051af2c3ca012d",
- "devtools_rev": "95d292626da26505b02417735f77e8922783b477",
+ "dartdoc_rev": "e476b1a11547163b76ac26381b90488f417bb261",
+ "devtools_rev": "d131d19091f6b89ac89486bd92440a25a523e8b0",
"ffi_rev": "18b2b549d55009ff594600b04705ff6161681e07",
"file_rev": "0132eeedea2933513bf230513a766a8baeab0c4f",
"fixnum_rev": "e0b17cc1f639c55a9c24947392c64b5a68992535",
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
index 8bd412e..cb3c5e7 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
@@ -8,9 +8,6 @@
/// [member] is an instance field.
///
-/// [name] is the field name that the [Namer] has picked for this field's
-/// storage, that is, the JavaScript property name.
-///
/// [needsGetter] and [needsSetter] represent if a getter or a setter
/// respectively is needed. There are many factors in this, for example, if the
/// accessor can be inlined.
@@ -18,23 +15,25 @@
/// [needsCheckedSetter] indicates that a checked getter is needed, and in this
/// case, [needsSetter] is always false. [needsCheckedSetter] is only true when
/// type assertions are enabled (checked mode).
-typedef AcceptField = void Function(FieldEntity member, js.Name name,
- bool needsGetter, bool needsSetter, bool needsCheckedSetter);
+typedef AcceptField = void Function(FieldEntity member, bool needsGetter,
+ bool needsSetter, bool needsCheckedSetter);
class FieldVisitor {
final JElementEnvironment _elementEnvironment;
final CodegenWorld _codegenWorld;
final NativeData _nativeData;
- final Namer _namer;
final JClosedWorld _closedWorld;
FieldVisitor(this._elementEnvironment, this._codegenWorld, this._nativeData,
- this._namer, this._closedWorld);
+ this._closedWorld);
- /// Invokes [f] for each of the fields of [element].
+ /// Invokes [f] for each of the fields of [cls].
///
- /// When visiting the instance fields of a class, the fields of its superclass
- /// are also visited if the class is instantiated.
+ /// If the class is directly instantiated, the fields of the superclasses are
+ /// also visited. These are required for creating a constructor that
+ /// initializes all the fields of the class.
+ ///
+ /// If the class is not directly instantiated
void visitFields(AcceptField f, ClassEntity cls) {
assert(
cls != null, failedAt(NO_LOCATION_SPANNABLE, 'Expected a ClassEntity'));
@@ -43,54 +42,65 @@
// If the class is never instantiated we still need to set it up for
// inheritance purposes, but we can simplify its JavaScript constructor.
- bool isInstantiated =
+ bool isDirectlyInstantiated =
_codegenWorld.directlyInstantiatedClasses.contains(cls);
void visitField(FieldEntity field, {ClassEntity holder}) {
- bool isMixinNativeField =
- isNativeClass && _elementEnvironment.isMixinApplication(holder);
-
- // See if we can dynamically create getters and setters.
- // We can only generate getters and setters for [element] since
- // the fields of super classes could be overwritten with getters or
- // setters.
+ // Simple getters and setters are generated in the emitter rather than
+ // being compiled through the SSA pipeline.
bool needsGetter = false;
bool needsSetter = false;
- if (isMixinNativeField || holder == cls) {
+
+ // In the J-model, instance members of a mixin are copied into the mixin
+ // application. At run time the methods are copied from the mixin's
+ // prototype to the mixin application's prototype. So we don't want to
+ // generate getters and setters for a field in a mixin application.
+ //
+ // A exception is when the mixin is used in a native class.
+ //
+ // TODO(sra): Figure out why native classes are different. It would seem
+ // that the native class methods are on an interceptor class and therefore
+ // the mixin application would be constructed just like any other class.
+ //
+ // TODO(49536): The only mixins-that-have-fields used on native classes
+ // come from extending custom elements. Mixins used in, say, `dart:html`
+ // have no fields. After removing custom elements, enforce that mixins in
+ // native classes have no fields.
+ bool isMixinApplication = _elementEnvironment.isMixinApplication(holder);
+ bool isMixinNativeField = isNativeClass && isMixinApplication;
+
+ // Generate getters and setters for fields of [cls] only, since the fields
+ // of super classes are the responsibility of the superclass.
+ if (isMixinNativeField || (cls == holder && !isMixinApplication)) {
needsGetter = fieldNeedsGetter(field);
needsSetter = fieldNeedsSetter(field);
}
- if ((isInstantiated && !_nativeData.isNativeClass(cls)) ||
+ if ((isDirectlyInstantiated && !isNativeClass) ||
needsGetter ||
needsSetter) {
- js.Name fieldName = _namer.instanceFieldPropertyName(field);
bool needsCheckedSetter = false;
- if (_closedWorld.annotationsData
+ if (needsSetter &&
+ _closedWorld.annotationsData
.getParameterCheckPolicy(field)
.isEmitted &&
- needsSetter &&
- !canAvoidGeneratedCheckedSetter(field)) {
+ !_canAvoidGeneratedCheckedSetter(field)) {
needsCheckedSetter = true;
needsSetter = false;
}
// Getters and setters with suffixes will be generated dynamically.
- f(field, fieldName, needsGetter, needsSetter, needsCheckedSetter);
+ f(field, needsGetter, needsSetter, needsCheckedSetter);
}
}
- // TODO(kasperl): We should make sure to only emit one version of
- // overridden fields. Right now, we rely on the ordering so the
- // fields pulled in from mixins are replaced with the fields from
- // the class definition.
-
- // If a class is not instantiated then we add the field just so we can
- // generate the field getter/setter dynamically. Since this is only
- // allowed on fields that are in [element] we don't need to visit
- // superclasses for non-instantiated classes.
_elementEnvironment.forEachClassMember(cls,
(ClassEntity holder, MemberEntity member) {
- if (cls != holder && !isInstantiated) return;
+ // Classes that are not directly instantiated do not use the JavaScript
+ // constructor function to allocate and initialize an object. We don't
+ // need to visit the superclasses since their fields are not used by the
+ // JavaScript constructor and their getters and setters are inherited.
+ if (cls != holder && !isDirectlyInstantiated) return;
+
if (member.isField && !member.isStatic) {
visitField(member, holder: holder);
}
@@ -120,7 +130,7 @@
false;
}
- bool canAvoidGeneratedCheckedSetter(FieldEntity member) {
+ bool _canAvoidGeneratedCheckedSetter(FieldEntity member) {
// We never generate accessors for top-level/static fields.
if (!member.isInstanceMember) return true;
DartType type = _elementEnvironment.getFieldType(member);
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 112b504..4b65322 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -1032,8 +1032,8 @@
{bool isHolderInterceptedClass = false, ClassEntity cls}) {
List<Field> fields = [];
- void visitField(FieldEntity field, js.Name name, bool needsGetter,
- bool needsSetter, bool needsCheckedSetter) {
+ void visitField(FieldEntity field, bool needsGetter, bool needsSetter,
+ bool needsCheckedSetter) {
int getterFlags = 0;
if (needsGetter) {
if (!_interceptorData.fieldHasInterceptedGetter(field)) {
@@ -1071,6 +1071,7 @@
constantValue = fieldData.constantValue;
}
+ js.Name name = _namer.instanceFieldPropertyName(field);
js.Name accessorName = _namer.fieldAccessorName(field);
fields.add(Field(
@@ -1086,7 +1087,7 @@
}
FieldVisitor visitor = FieldVisitor(
- _elementEnvironment, _codegenWorld, _nativeData, _namer, _closedWorld);
+ _elementEnvironment, _codegenWorld, _nativeData, _closedWorld);
visitor.visitFields(visitField, cls);
return fields;
diff --git a/tools/VERSION b/tools/VERSION
index d9d140a..d5cd0a9 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 19
PATCH 0
-PRERELEASE 46
+PRERELEASE 47
PRERELEASE_PATCH 0
\ No newline at end of file