Index: frog/member.dart |
diff --git a/frog/member.dart b/frog/member.dart |
index f2481da856da483d5dbecefc5793b10d64831e46..22824d4c326aefe0d1bb378bf4dae678514e7669 100644 |
--- a/frog/member.dart |
+++ b/frog/member.dart |
@@ -1005,6 +1005,32 @@ class MethodMember extends Member { |
: '${declaringType.jsname}.call($argsString)'; |
return new Value(target.type, code, node.span); |
} else { |
+ if (declaringType.isAbstract) { |
+ // Warn at the constructor location |
+ world.warning('Cannot instantiate abstract class ${declaringType.name}', |
+ node.span); |
+ |
+ // Now make a message explaining why the type is abstract. |
+ |
+ // Get abstract members grouped by type |
+ var members = groupBy(declaringType.inheritedMembers.getValues().filter( |
+ (m) => m.isAbstract), (m) => m.declaringType); |
+ |
+ var msg = new StringBuffer('Type ${declaringType.name} is abstract ' |
+ + 'because it does not implement the following members'); |
+ |
+ var types = members.getKeys(); |
+ types.sort((x, y) => x.name.compareTo(y.name)); |
+ for (var type in types) { |
+ if (type != types[0]) msg.add(';'); |
+ msg.add(' from type ${type.name}: '); |
+ msg.add(Strings.join(map(members[type], (m) => m.name), ', ')); |
+ } |
+ |
+ // Warn at the type's location |
+ world.warning(msg.toString(), declaringType.span); |
+ } |
+ |
var code = (constructorName != '') |
? 'new ${declaringType.jsname}.${constructorName}\$ctor($argsString)' |
: 'new ${declaringType.jsname}($argsString)'; |