dev_compiler icon indicating copy to clipboard operation
dev_compiler copied to clipboard

fields that implement extension members don't work

Open jmesserly opened this issue 9 years ago • 7 comments

Split from #520

The following test fails, because defineExtensionMember does not find a property descriptor for MyList.length, so it does not create [dartx.length] and thus ListMixin.forEach will throw.

import 'dart:collection';
import 'package:expect/expect.dart';

class MyList extends ListBase {
  int length = 4;
  int operator[](int x) => 42;
  void operator[]=(int x, val) {}
}

main() {
  var x = new MyList();
  int z = 0;
  // runtime error in here, but the bug was in how MyList type was set up
  x.forEach((y) { z += y; });
  Expect.equals(z, 4 * 42);
}

jmesserly avatar May 04 '16 20:05 jmesserly

@vsmenon @jacob314 -- thoughts on priority of this one?

jmesserly avatar May 04 '16 20:05 jmesserly

(also I think Jacob's fix might address this?)

jmesserly avatar May 04 '16 20:05 jmesserly

I don't think my CL impacts this as I only change behavior for native classes with extensions.

jacob314 avatar May 05 '16 20:05 jacob314

Here's another example I'm seeing (with same MyList above):

main() {
  dynamic x = new MyList();
  print(x.isEmpty);
}

This prints undefined. Same result if we replace dynamic with var.

vsmenon avatar May 06 '16 17:05 vsmenon

ah chatted about that example, it's probably the same issue. Any ListBase/Mixin that uses a length field will be broken (because that is what ListMixin does: implement all members in terms of length and [] []=). Either we need to know to emit a getter/setter pair for that at compile time, or the defineExtensionMembers helper needs to know that it should do so.

There's also a related issue that "length" shows up twice in the defineExtensionMembers list (probably once from the getter and once from the setter)

jmesserly avatar May 06 '16 18:05 jmesserly

Found a workaround, lowering back to P2.

This may be a different bug - changing length to a getter did not fix.

import 'dart:collection';

class MyList extends ListBase with ListMixin {
  int get length => 4;
  void set length(int x) {}
  int operator[](int x) => 42;
  void operator[]=(int x, val) {}
}

main() {
  dynamic x = new MyList();
  print(x.isEmpty);
}

vsmenon avatar May 06 '16 18:05 vsmenon

Ok, syncing up and now the getter version works. Sorry for the noise.

vsmenon avatar May 06 '16 18:05 vsmenon