Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

for-in codegen for dynamic case #166

Closed
@jmesserly

Description

@jmesserly

First off, we should verify that the static checker is working. Dart for-in loops should do the right static checks, and issue errors, e.g. if my Iterator is missing moveNext or current. So all statically typed cases will be fine, and caught at compile time.

The two problematic cases that I see are the dynamic ones:

    case1() {
      dynamic bogus = 123;
      for (var x in bogus) { ... }
    }

    class BogusIterable {
      get iterator {
        dynamic bogus = 123;
        return bogus;
      }
    }
    case2() {
      for (var x in new BogusIterable()) { ... }
    }

For case 1, we should call bogus.noSuchMethod with #iterator as the invocation symbol. Instead it will fail like:

Uncaught TypeError: Cannot read property 'Symbol(Symbol.iterator)' of ...

For case 2 we have a similar problem. It will fail inside dart_runtime JsIterator, in either the i.moveNext() or i.current calls.

Both of these need different fixes, I think. For case1, we need a dynamic variant of for-in loop. Probably we can insert a call like:

    for (let x of dart.diterable(bogus)) { ... }

this will return an object that does checks:

function diterable(obj) {
  // TODO(jmesserly): we only use this immediately in for-of loops and discard, so we could
  // cache and reuse the same instance for perf.
  return { [Symbol.iterator]() { return new JsIteratorChecked(dart.dload(obj, 'iterable')); } }
}

For case2, we need only JsIteratorChecked ... in codegen, if we don't think this.iterable is typed correctly--it doesn't have valid moveNext and current methods--we use JsIteratorChecked instead of JsIterator. JsIteratorChecked is identical to JsIterator, but uses dynamic dispatch for moveNext and current. We could even optimize it a little bit, and have JsIteratorChecked decide up-front if moveNext and current are there and have the right return types, and if so, use the faster JsIterator.

Last but not least, case3: we need checking on x in the for loop body, I suspect. Might be there already. Checker/coercion reifier should be the ones handling these.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions