Fix needsNoSuchMethod computation for abstractly instantiated classes

R=floitsch@google.com

Review-Url: https://codereview.chromium.org/2612253002 .
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 097940e..50c708f 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -908,7 +908,7 @@
     ClassSet classSet = getClassSet(base);
     ClassHierarchyNode node = classSet.node;
     if (query == ClassQuery.EXACT) {
-      return node.isDirectlyInstantiated && !hasConcreteMatch(base, selector);
+      return node.isExplicitlyInstantiated && !hasConcreteMatch(base, selector);
     } else if (query == ClassQuery.SUBCLASS) {
       return subclassesNeedNoSuchMethod(node);
     } else {
diff --git a/tests/compiler/dart2js/jsinterop/world_test.dart b/tests/compiler/dart2js/jsinterop/world_test.dart
index 1ddbd39..bed24f3 100644
--- a/tests/compiler/dart2js/jsinterop/world_test.dart
+++ b/tests/compiler/dart2js/jsinterop/world_test.dart
@@ -7,8 +7,10 @@
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/common.dart';
-import 'package:compiler/src/elements/elements.dart' show Element, ClassElement;
+import 'package:compiler/src/elements/elements.dart'
+    show ClassElement, PublicName;
 import 'package:compiler/src/js_backend/js_backend.dart';
+import 'package:compiler/src/universe/selector.dart';
 import 'package:compiler/src/world.dart';
 import '../type_test_helper.dart';
 
@@ -102,6 +104,8 @@
     ClassElement E = registerClass(env.getElement('E'));
     ClassElement F = registerClass(env.getElement('F'));
 
+    Selector nonExisting = new Selector.getter(const PublicName('nonExisting'));
+
     Expect.equals(Interceptor.superclass, Object_);
     Expect.equals(JavaScriptObject.superclass, Interceptor);
 
@@ -128,6 +132,15 @@
             world.isAbstractlyInstantiated(cls),
             "Expected $name to be abstractly instantiated in `${mainSource}`:"
             "\n${world.dump(cls)}");
+        Expect.isTrue(
+            world.needsNoSuchMethod(cls, nonExisting, ClassQuery.EXACT),
+            "Expected $name to need noSuchMethod for $nonExisting.");
+        Expect.isTrue(
+            world.needsNoSuchMethod(cls, nonExisting, ClassQuery.SUBCLASS),
+            "Expected $name to need noSuchMethod for $nonExisting.");
+        Expect.isTrue(
+            world.needsNoSuchMethod(cls, nonExisting, ClassQuery.SUBTYPE),
+            "Expected $name to need noSuchMethod for $nonExisting.");
       }
       if (indirectlyInstantiated.contains(name)) {
         isInstantiated = true;
diff --git a/tests/language/regress_28255_test.dart b/tests/language/regress_28255_test.dart
new file mode 100644
index 0000000..118fc6e
--- /dev/null
+++ b/tests/language/regress_28255_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// Regression test for issue 28255
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class Class {
+  noSuchMethod(i) => true;
+
+  foo() {
+    var o = this;
+    Expect.isFalse(o.bar is Null);
+    Expect.isTrue(o.bar != null);
+    Expect.equals(true.runtimeType, o.bar.runtimeType);
+  }
+}
+
+main() {
+  reflectClass(Class).newInstance(const Symbol(''), []).reflectee.foo();
+}