// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// 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.

// test w/ `pub run test -N omit_local_variable_types`

abstract class StringIterator<E> implements Iterable<E> {}

void printItems2(StringIterator<String> items) {
  for (String item in items) { // LINT
    print(item);
  }
}

abstract class StringIterator2 implements StringIterator<String> {}

void printItems3(StringIterator2 items) {
  for (String item in items) { // LINT
    print(item);
  }
}

void printItems(Iterable items) {
  for (String item in items) { // OK
    print(item);
  }
}

void foo() {
  final array = [];
  for (a in array) { // OK

  }
}

int goodGlobalVariable = 3, a = 4; // OK

Map<int, List<Person>> badGroupByZip(Iterable<Person> people) {
  Map<int, List<Person>> peopleByZip = <int, List<Person>>{}; // LINT

  for (Person person in people) { // LINT
    peopleByZip.putIfAbsent(person.zip, () => <Person>[]);
    peopleByZip[person.zip].add(person);
  }

  return peopleByZip;
}

Map<int, List<Person>> goodGroupByZip(Iterable<Person> people) {
  var peopleByZip = <int, List<Person>>{}; // OK

  for (final person in people) { // OK
    peopleByZip.putIfAbsent(person.zip, () => <Person>[]);
    peopleByZip[person.zip].add(person);
  }

  return peopleByZip;
}

class Person {
  int zip = 3; // OK

  Person() {
    Iterable a = [], b = new Iterable.empty(); // OK
    Iterable c = new Iterable.empty(), d = new Iterable.empty(); // LINT
  }
}

class LinkedListNode {
  LinkedListNode next;
}
void traverse(LinkedListNode head) {
  for (LinkedListNode node = head; node != null; node = node.next) { // LINT
    // doSomething
  }
}
