// 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.
//
// VMOptions=--optimization-counter-threshold=1000 --no-background-compilation

// @dart = 2.9

// Regression test for correct LICM and type propagation.

class Attribute {
  final id = 123;
}

abstract class Name {
  Name(this.name);
  final String name;
  get attr;

  @pragma('vm:prefer-inline')
  int compareTo(other) {
    int nameCompare = name.compareTo(other.name);
    if (nameCompare != 0) return nameCompare;
    if (attr == null) return 0;
    return attr.id - other.attr.id;
  }
}

class AName extends Name {
  AName() : super("abc");
  final attr = new Attribute();
}

class BName extends Name {
  BName(name) : super(name);
  get attr => null;
}

class Member {
  Member(this.name);
  var name;
}

Member find(List<Member> members, Name name) {
  int low = 0, high = members.length - 1;
  while (low <= high) {
    int mid = low + ((high - low) >> 1);
    Member pivot = members[mid];
    int comparison = name.compareTo(pivot.name);
    if (comparison < 0) {
      high = mid - 1;
    } else if (comparison > 0) {
      low = mid + 1;
    } else {
      return pivot;
    }
  }
  return null;
}

main() {
  var list = [
    new Member(new AName()),
    new Member(new BName("a")),
    new Member(new BName("b")),
    new Member(new BName("c")),
    new Member(new BName("d"))
  ];

  find(list, new AName());
  find(list, new BName("e"));
  find(list, new BName("b"));
  for (var i = 0; i < 1000; ++i) {
    find(list, new BName("b"));
    find(list, new BName("e"));
  }
}
