// Copyright (c) 2020, 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.
// @dart=2.9
import 'dart:collection';

class ConstIterable extends IterableBase<int> {
  const ConstIterable();

  Iterator<int> get iterator => <int>[].iterator;
}

const int fortyTwo = 42;
const dynamic fortyTwoAsDynamic = ((fortyTwo as dynamic) * 2) ~/ 2;

const List<String> nullList = null;
const List<String> foo = ["hello", "world"];
List<String> get fooAsGetter => const ["hello", "world"];
const List<String> bar = [...foo, "!"];
var barAsVar = [...foo, "!"];
List<String> get barAsGetter => const [...foo, "!"];
const List<String> barWithNullSpread = [...foo, ...nullList];
const List<String> barWithIntSpread = [...foo, ...fortyTwo];
const List<String> barWithIntDynamicSpread = [...foo, ...fortyTwoAsDynamic];
const List<String> barWithMapSpread = [...foo, ...quux];
const List<String> barWithCustomIterableSpread1 = [
  ...bar,
  ...const CustomIterable()
];
const List<String> barWithCustomIterableSpread2 = [...bar, ...CustomIterable()];
const customIterable = const CustomIterable();
const List<String> barWithCustomIterableSpread3 = [...bar, ...customIterable];
const List<String> listConcat = ["Hello"] + ["World"];

const Set<String> nullSet = null;
const Set<String> baz = {"hello", "world"};
Set<String> get bazAsGetter => const {"hello", "world"};
const Set<String> qux = {...baz, "!"};
Set<String> get quxAsGetter => const {...baz, "!"};
const Set<String> quxWithNullSpread = {...baz, ...nullSet};
const Set<String> quxWithIntSpread = {...baz, ...fortyTwo};
const Set<String> quxWithMapSpread = {...baz, ...quux};
const Set<String> quxWithCustomIterableSpread1 = {
  ...baz,
  ...const CustomIterable()
};
const Set<String> quxWithCustomIterableSpread2 = {...baz, ...CustomIterable()};
const Set<String> quxWithCustomIterableSpread3 = {...baz, customIterable};
const Set<dynamic> setWithNonPrimitiveEquals = {const WithEquals(42)};
const Set<dynamic> setWithDuplicates = {42, 42};

const Map<String, String> nullMap = null;
const Map<String, String> quux = {"hello": "world"};
Map<String, String> get quuxAsGetter => const {"hello": "world"};
const Map<String, String> quuz = {...quux, "!": "bye!"};
Map<String, String> get quuzAsGetter => const {...quux, "!": "bye!"};
const Map<String, String> quuzWithNullSpread = {...quux, ...nullMap};
const Map<String, String> quuzWithIntSpread = {...quux, ...fortyTwo};
const Map<String, String> quuzWithSetSpread = {...quux, ...baz};
const Map<String, String> mapWithSetSpread = {...baz};
const Map<String, String> mapWithCustomMap1 = {...const CustomMap()};
const Map<String, String> mapWithCustomMap2 = {...CustomMap()};
const Map<String, String> customMap = const CustomMap();
const Map<String, String> mapWithCustomMap3 = {...customMap};
const Map<dynamic, int> mapWithNonPrimitiveEqualsKey = {
  const WithEquals(42): 42
};
const Map<int, int> mapWithDuplicates = {42: 42, 42: 42};

class WithEquals {
  final int i;
  const WithEquals(this.i);
  operator ==(Object o) {
    return o is WithEquals && (o as WithEquals).i == i;
  }
}

class CustomIterable extends IterableBase<String> {
  const CustomIterable();
  Iterator<String> get iterator => <String>[].iterator;
}

class CustomMap implements Map<String, String> {
  const CustomMap();

  @override
  Iterable<MapEntry<String, String>> get entries => [];

  @override
  String operator [](Object key) => throw new UnimplementedError();

  @override
  void operator []=(String key, String value) => throw new UnimplementedError();

  @override
  Map<RK, RV> cast<RK, RV>() => throw new UnimplementedError();

  @override
  void clear() => throw new UnimplementedError();

  @override
  bool containsKey(Object key) => throw new UnimplementedError();

  @override
  bool containsValue(Object value) => throw new UnimplementedError();

  @override
  bool get isEmpty => throw new UnimplementedError();

  @override
  bool get isNotEmpty => throw new UnimplementedError();

  @override
  Iterable<String> get keys => throw new UnimplementedError();

  @override
  int get length => throw new UnimplementedError();

  @override
  String remove(Object key) => throw new UnimplementedError();

  @override
  Iterable<String> get values => throw new UnimplementedError();

  @override
  void addAll(Map<String, String> other) => throw new UnimplementedError();

  @override
  void addEntries(Iterable<MapEntry<String, String>> newEntries) =>
      throw new UnimplementedError();

  @override
  void forEach(void f(String key, String value)) =>
      throw new UnimplementedError();

  @override
  String putIfAbsent(String key, String ifAbsent()) =>
      throw new UnimplementedError();

  @override
  void updateAll(String update(String key, String value)) =>
      throw new UnimplementedError();

  @override
  void removeWhere(bool predicate(String key, String value)) =>
      throw new UnimplementedError();

  String update(String key, String update(String value), {String ifAbsent()}) =>
      throw new UnimplementedError();

  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> f(String key, String value)) =>
      throw new UnimplementedError();
}

main() {
  print(bar);
  print(qux);
  print(quuz);
  print({"hello"});
  print(const {"hello"});
}
