#491. Null-check operator tests improved and new ones added
diff --git a/LanguageFeatures/nnbd/null_check_operator_A01_t01.dart b/LanguageFeatures/nnbd/null_check_operator_A01_t01.dart
index 9d8f92b..a4a8f90 100644
--- a/LanguageFeatures/nnbd/null_check_operator_A01_t01.dart
+++ b/LanguageFeatures/nnbd/null_check_operator_A01_t01.dart
@@ -8,18 +8,34 @@
  * runtime error if v is null, and otherwise evaluates to v.
  *
  * @description Check that an expression of the form e! evaluates e to a value
- * v, throws a runtime error if v is null
+ * v, throws a runtime error if v is null. Test class
  * @author sgrekhov@unipro.ru
+ * @issue 39723
+ * @issue 39724
  */
 // SharedOptions=--enable-experiment=non-nullable
 import "../../Utils/expect.dart";
 
-class A {}
+class A {
+  foo() {}
+  Object? get getNull => null;
+  Object? operator [](int index) => null;
+}
 
 main() {
   A? a = null;
   Expect.throws(() {a!;});
-  Expect.throws(() {null!;});
-  String? s = null;
-  Expect.throws(() {s!;});
+  Expect.throws(() {a!.foo();});
+  Expect.throws(() {a![42];});
+  Expect.throws(() {a!?.foo();});
+  Expect.throws(() {a!?.[42];});
+  a = new A();
+  if (a != null) {
+    Expect.throws(() {
+      a.getNull!;
+    });
+    Expect.throws(() {
+      a[42]!;
+    });
+  }
 }
diff --git a/LanguageFeatures/nnbd/null_check_operator_A01_t02.dart b/LanguageFeatures/nnbd/null_check_operator_A01_t02.dart
index 3e2c27c..1f490d9 100644
--- a/LanguageFeatures/nnbd/null_check_operator_A01_t02.dart
+++ b/LanguageFeatures/nnbd/null_check_operator_A01_t02.dart
@@ -8,21 +8,31 @@
  * runtime error if v is null, and otherwise evaluates to v.
  *
  * @description Check that an expression of the form e! evaluates e to a value
- * v if v is not null
+ * v, throws a runtime error if v is null. Test function type
  * @author sgrekhov@unipro.ru
+ * @issue 39723
+ * @issue 39724
  */
 // SharedOptions=--enable-experiment=non-nullable
 import "../../Utils/expect.dart";
 
-class A {}
+Object? foo(int i) => null;
+Object? bar<T>(T t) => null;
 
 main() {
-  A a1 = new A();
-  A? a2 = a1;
+  Function? f1 = null;
+  Expect.throws(() {f1!(42);});
+  f1 = foo;
+  if (f1 != null) {
+    Expect.throws(() {
+      f1(42)!;
+    });
+  }
 
-  Expect.equals(a1, a1!);
-  Expect.equals(a1, a2!);
-
-  String? s = "Lily was here";
-  Expect.equals("Lily was here", s!);
+  Function f2 = null;
+  Expect.throws(() {f2<int>!(42);});
+  f2 = bar;
+  if (f2 != null) {
+    Expect.throws(() {f2<int>(42)!;});
+  }
 }
diff --git a/LanguageFeatures/nnbd/null_check_operator_A01_t03.dart b/LanguageFeatures/nnbd/null_check_operator_A01_t03.dart
new file mode 100644
index 0000000..d615f88
--- /dev/null
+++ b/LanguageFeatures/nnbd/null_check_operator_A01_t03.dart
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+/**
+ * @assertion An expression of the form e! evaluates e to a value v, throws a
+ * runtime error if v is null, and otherwise evaluates to v.
+ *
+ * @description Check that an expression of the form e! evaluates e to a value
+ * v, throws no runtime error if v is not null. Test function type
+ * @author sgrekhov@unipro.ru
+ * @issue 39723
+ */
+// SharedOptions=--enable-experiment=non-nullable
+
+class A {
+  foo() {}
+  Object? get getValue => "Lily was here";
+  int? operator [](int index) => index;
+}
+
+main() {
+  A? a = new A();
+  a!;
+  a!.foo();
+  a![42];
+  a!?.foo();
+  a!?.[42];
+  if (a != null) {
+    a.getValue!;
+    a[42]!;
+  }
+}
diff --git a/LanguageFeatures/nnbd/null_check_operator_A01_t04.dart b/LanguageFeatures/nnbd/null_check_operator_A01_t04.dart
new file mode 100644
index 0000000..32dc24e
--- /dev/null
+++ b/LanguageFeatures/nnbd/null_check_operator_A01_t04.dart
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+/**
+ * @assertion An expression of the form e! evaluates e to a value v, throws a
+ * runtime error if v is null, and otherwise evaluates to v.
+ *
+ * @description Check that an expression of the form e! evaluates e to a value
+ * v, throws no runtime error if v is not null. Test function type
+ * @author sgrekhov@unipro.ru
+ * @issue 39723
+ */
+// SharedOptions=--enable-experiment=non-nullable
+
+Object? foo(int i) => "Lily was here";
+Object? bar<T>(T t) => 42;
+
+main() {
+  Function? f1 = foo;
+  f1!(42);
+  if (f1 != null) {
+      f1(42)!;
+  }
+
+  Function f2 = bar;
+  f2<int>!(42);
+  if (f2 != null) {
+    f2<int>(42)!;
+  }
+}
diff --git a/LanguageFeatures/nnbd/null_check_operator_A01_t05.dart b/LanguageFeatures/nnbd/null_check_operator_A01_t05.dart
new file mode 100644
index 0000000..9ec3dcd
--- /dev/null
+++ b/LanguageFeatures/nnbd/null_check_operator_A01_t05.dart
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+/**
+ * @assertion An expression of the form e! evaluates e to a value v, throws a
+ * runtime error if v is null, and otherwise evaluates to v.
+ *
+ * @description Check that an expression of the form e! evaluates e to a value
+ * v, throws no runtime error if v is not null. Test 'this'
+ * @author sgrekhov@unipro.ru
+ * @issue 39723
+ * @issue 39598
+ */
+// SharedOptions=--enable-experiment=non-nullable
+
+class A {
+  foo() {}
+  Object? get getValue => "Lily was here";
+  int? operator [](int index) => index;
+
+  test() {
+    this!;          //# 01: static type warning
+    this!.foo();    //# 02: static type warning
+    this![42];      //# 03: static type warning
+    this!?.foo();   //# 04: static type warning
+    this!?.[42];    //# 05: static type warning
+    this.getValue!;
+    this[42]!;
+  }
+}
+
+main() {
+  A a = new A();
+  a.test();
+}
diff --git a/LanguageFeatures/nnbd/null_check_operator_A01_t06.dart b/LanguageFeatures/nnbd/null_check_operator_A01_t06.dart
new file mode 100644
index 0000000..90327ed
--- /dev/null
+++ b/LanguageFeatures/nnbd/null_check_operator_A01_t06.dart
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+/**
+ * @assertion An expression of the form e! evaluates e to a value v, throws a
+ * runtime error if v is null, and otherwise evaluates to v.
+ *
+ * @description Check that an expression of the form e! evaluates e to a value
+ * v, throws no runtime error if v is not null. Test 'this!()' and 'this()!'
+ * @author sgrekhov@unipro.ru
+ * @issue 39723
+ * @issue 39598
+ */
+// SharedOptions=--enable-experiment=non-nullable,extension-methods
+import "../../Utils/expect.dart";
+class C {}
+
+extension on C {
+  test() {
+    Expect.equals("Lily was here: 42", this!(42));  //# 01: static type warning
+    Expect.equals("Lily was here: 42", this(42)!);  //# 02: static type warning
+  }
+  String call(int v) => "Lily was here: $v";
+}
+
+main() {
+  C c = new C();
+  c.test();
+}
\ No newline at end of file
diff --git a/LanguageFeatures/nnbd/null_check_operator_A01_t07.dart b/LanguageFeatures/nnbd/null_check_operator_A01_t07.dart
new file mode 100644
index 0000000..d794d09
--- /dev/null
+++ b/LanguageFeatures/nnbd/null_check_operator_A01_t07.dart
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+/**
+ * @assertion An expression of the form e! evaluates e to a value v, throws a
+ * runtime error if v is null, and otherwise evaluates to v.
+ *
+ * @description Check that an expression of the form e! evaluates e to a value
+ * v, throws no runtime error if v is not null. Test 'super'
+ * @author sgrekhov@unipro.ru
+ * @issue 39723
+ * @issue 39598
+ */
+// SharedOptions=--enable-experiment=non-nullable
+
+class A {
+  foo() {}
+  Object? get getValue => "Lily was here";
+  int? operator [](int index) => index;
+}
+
+class C extends A {
+  test() {
+    super!;          //# 01: static type warning
+    super!.foo();    //# 02: static type warning
+    super![42];      //# 03: static type warning
+    super!?.foo();   //# 04: static type warning
+    super!?.[42];    //# 05: static type warning
+    super.getValue!;
+    super[42]!;
+  }
+}
+
+main() {
+  C c = new C();
+  c.test();
+}