Check mixin of black-listed types.

BUG=http://dartbug.com/12445
R=karlklose@google.com

Review URL: https://codereview.chromium.org//25844002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@28197 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 7a27b1d..af4208d 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -3606,7 +3606,8 @@
         DartType supertype = resolveSupertype(element, superMixin.superclass);
         Link<Node> link = superMixin.mixins.nodes;
         while (!link.isEmpty) {
-          supertype = applyMixin(supertype, resolveType(link.head), node);
+          supertype = applyMixin(
+              supertype, checkMixinType(link.head), link.head);
           link = link.tail;
         }
         element.supertype = supertype;
@@ -3657,6 +3658,17 @@
     return element.computeType(compiler);
   }
 
+  /// Resolves the mixed type for [mixinNode] and checks that the the mixin type
+  /// is not black-listed. The mixin type is returned.
+  DartType checkMixinType(TypeAnnotation mixinNode) {
+    DartType mixinType = resolveType(mixinNode);
+    if (isBlackListed(mixinType)) {
+      compiler.reportError(mixinNode,
+          MessageKind.CANNOT_MIXIN, {'type': mixinType});
+    }
+    return mixinType;
+  }
+
   DartType visitNamedMixinApplication(NamedMixinApplication node) {
     compiler.ensure(element != null);
     compiler.ensure(element.resolutionState == STATE_STARTED);
@@ -3670,10 +3682,10 @@
     DartType supertype = resolveSupertype(element, node.superclass);
     Link<Node> link = node.mixins.nodes;
     while (!link.tail.isEmpty) {
-      supertype = applyMixin(supertype, resolveType(link.head), link.head);
+      supertype = applyMixin(supertype, checkMixinType(link.head), link.head);
       link = link.tail;
     }
-    doApplyMixinTo(element, supertype, resolveType(link.head));
+    doApplyMixinTo(element, supertype, checkMixinType(link.head));
     return element.computeType(compiler);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 7d5dcbf..3c3729e 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -668,6 +668,19 @@
   static const MessageKind CANNOT_IMPLEMENT = const MessageKind(
       "Error: '#{type}' cannot be implemented.");
 
+  static const MessageKind CANNOT_MIXIN = const MessageKind(
+      "Error: The type '#{type}' can't be mixed in.",
+      howToFix: "Try removing '#{type}' from the 'with' clause.",
+      examples: const ["""
+class C extends Object with String {}
+
+main() => new C();                       
+""", """
+typedef C = Object with String;
+
+main() => new C();                       
+"""]);
+
   static const MessageKind DUPLICATE_EXTENDS_IMPLEMENTS = const MessageKind(
       "Error: '#{type}' can not be both extended and implemented.");
 
diff --git a/tests/language/mixin_black_listed_test.dart b/tests/language/mixin_black_listed_test.dart
new file mode 100644
index 0000000..809274b
--- /dev/null
+++ b/tests/language/mixin_black_listed_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2013, 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.
+
+// Check mixin of black-listed types.
+
+import 'package:expect/expect.dart';
+
+class C {}
+class D {}
+
+class C1 extends Object
+with String /// 01: compile-time error
+{}
+
+class D1 extends Object with C
+, Null /// 02: compile-time error
+{}
+
+class E1 extends Object with
+int, /// 03: compile-time error
+C {}
+
+class F1 extends Object with C
+, double /// 04: compile-time error
+, D {}
+
+typedef C2 = Object with num; /// 05: compile-time error
+
+typedef D2 = Object with C
+, bool /// 06: compile-time error
+;
+
+typedef E2 = Object with
+String, /// 07: compile-time error
+C;
+
+typedef F2 = Object with C,
+dynamic, /// 08: compile-time error
+D;
+
+
+main() {
+  Expect.isNotNull(new C1());
+  Expect.isNotNull(new D1());
+  Expect.isNotNull(new E1());
+  Expect.isNotNull(new F1());
+  Expect.isNotNull(new C2()); /// 05: continued
+  Expect.isNotNull(new D2());
+  Expect.isNotNull(new E2());
+  Expect.isNotNull(new F2());
+}