Index: frog/frogsh |
diff --git a/frog/frogsh b/frog/frogsh |
index d520b95b5e4dfb92e96bfce9d5ec708554830f93..3903ba90a455f46ed0af800051ae6b5964e07fc8 100755 |
--- a/frog/frogsh |
+++ b/frog/frogsh |
@@ -1092,6 +1092,9 @@ ImmutableMap.prototype.containsKey = function(key) { |
ImmutableMap.prototype.$setindex = function(key, value) { |
$throw(const$14/*const IllegalAccessException()*/); |
} |
+ImmutableMap.prototype.putIfAbsent = function(key, ifAbsent) { |
+ $throw(const$14/*const IllegalAccessException()*/); |
+} |
ImmutableMap.prototype.forEach$1 = ImmutableMap.prototype.forEach; |
ImmutableMap.prototype.getKeys$0 = function() { |
return this.getKeys(); |
@@ -1291,6 +1294,13 @@ HashMapImplementation.prototype.$index = function(key) { |
if (index < 0) return null; |
return this._values.$index(index); |
} |
+HashMapImplementation.prototype.putIfAbsent = function(key, ifAbsent) { |
+ var index = this._probeForLookup(key); |
+ if (index >= 0) return this._values.$index(index); |
+ var value = ifAbsent(); |
+ this.$setindex(key, value); |
+ return value; |
+} |
HashMapImplementation.prototype.remove = function(key) { |
var index = this._probeForLookup(key); |
if (index >= 0) { |
@@ -1729,6 +1739,14 @@ LinkedHashMapImplementation.prototype.$index = function(key) { |
if (entry == null) return null; |
return entry.get$element().get$value(); |
} |
+LinkedHashMapImplementation.prototype.putIfAbsent = function(key, ifAbsent) { |
+ var value = this.$index(key); |
+ if ((this.$index(key) == null) && !(this.containsKey(key))) { |
+ value = ifAbsent(); |
+ this.$setindex(key, value); |
+ } |
+ return value; |
+} |
LinkedHashMapImplementation.prototype.getKeys = function() { |
var list = new ListFactory(this.get$length()); |
var index = 0; |
@@ -14197,12 +14215,39 @@ MethodMember.prototype.invoke = function(context, node, target, args, isDynamic) |
return new Value(this.get$inferredResult(), code, node.span, true); |
} |
MethodMember.prototype._invokeConstructor = function(context, node, target, args, argsString) { |
+ var $0; |
this.declaringType.markUsed(); |
if (!$notnull_bool(target.isType)) { |
var code = (this.get$constructorName() != '') ? ('' + this.declaringType.get$jsname() + '.' + this.get$constructorName() + '\$ctor.call(' + argsString + ')') : ('' + this.declaringType.get$jsname() + '.call(' + argsString + ')'); |
return new Value(target.type, code, node.span, true); |
} |
else { |
+ if ($notnull_bool(this.declaringType.get$isAbstract())) { |
+ $globals.world.warning(('Cannot instantiate abstract class ' + this.declaringType.name), node.span); |
+ var members = groupBy((($0 = this.declaringType.get$inheritedMembers().getValues().filter$1((function (m) { |
+ return m.get$isAbstract(); |
+ }) |
+ )) && $0.is$Iterable()), (function (m) { |
+ return m.get$declaringType(); |
+ }) |
+ ); |
+ var msg = new StringBufferImpl(('Type ' + this.declaringType.name + ' is abstract ') + 'because it does not implement the following members'); |
+ var types = members.getKeys$0(); |
+ types.sort$1((function (x, y) { |
+ return x.get$name().compareTo$1(y.get$name()); |
+ }) |
+ ); |
+ for (var $i = types.iterator$0(); $i.hasNext$0(); ) { |
+ var type = $i.next$0(); |
+ if ($notnull_bool($ne(type, types.$index(0)))) msg.add$1(';'); |
+ msg.add$1((' from type ' + type.get$name() + ': ')); |
+ msg.add$1(Strings.join(map((($0 = members.$index(type)) && $0.is$Iterable()), (function (m) { |
+ return m.get$name(); |
+ }) |
+ ), ', ')); |
+ } |
+ $globals.world.warning(msg.toString$0(), this.declaringType.get$span()); |
+ } |
var code = (this.get$constructorName() != '') ? ('new ' + this.declaringType.get$jsname() + '.' + this.get$constructorName() + '\$ctor(' + argsString + ')') : ('new ' + this.declaringType.get$jsname() + '(' + argsString + ')'); |
if ($notnull_bool(this.isConst) && (node instanceof lang_NewExpression) && $notnull_bool(node.get$dynamic().get$isConst())) { |
return this._invokeConstConstructor(node, $assert_String(code), target, args); |
@@ -19455,6 +19500,45 @@ lang_Type.prototype.getAllMembers = function() { |
lang_Type.prototype.hashCode = function() { |
return this.name.hashCode(); |
} |
+lang_Type.prototype.get$isAbstract = function() { |
+ if (this._isAbstract == null) { |
+ if ($notnull_bool(this.get$isClass())) { |
+ this._isAbstract = $assert_bool(this.get$inheritedMembers().getValues().some$1((function (m) { |
+ return m.get$isAbstract(); |
+ }) |
+ )); |
+ } |
+ else { |
+ this._isAbstract = true; |
+ } |
+ } |
+ return this._isAbstract; |
+} |
+lang_Type.prototype.get$inheritedMembers = function() { |
+ var $0; |
+ if (this._inheritedMembers == null) { |
+ this._inheritedMembers = (($0 = this._getInheritedMembers($map([]))) && $0.is$Map$String$Member()); |
+ } |
+ return this._inheritedMembers; |
+} |
+lang_Type.prototype._getInheritedMembers = function(flattened) { |
+ if (this.get$interfaces() != null) { |
+ var $list = this.get$interfaces(); |
+ for (var $i = 0;$i < $list.length; $i++) { |
+ var i = $list.$index($i); |
+ i._getInheritedMembers(flattened); |
+ } |
+ } |
+ if (this.get$parent() != null) { |
+ this.get$parent()._getInheritedMembers(flattened); |
+ } |
+ var $list = this.getAllMembers().getValues(); |
+ for (var $i = this.getAllMembers().getValues().iterator$0(); $i.hasNext$0(); ) { |
+ var m = $i.next$0(); |
+ flattened.$setindex(m.get$name(), m); |
+ } |
+ return flattened; |
+} |
lang_Type.prototype._checkOverride = function(member) { |
var parentMember = this._getMemberInParents(member.name); |
if ($notnull_bool($ne(parentMember, null))) { |
@@ -20076,7 +20160,7 @@ DefinedType.prototype.set$isUsed = function(value) { return this.isUsed = value; |
DefinedType.prototype.get$isNativeType = function() { return this.isNativeType; }; |
DefinedType.prototype.set$isNativeType = function(value) { return this.isNativeType = value; }; |
DefinedType.prototype.setDefinition = function(def) { |
- $assert(this.definition == null, "definition == null", "type.dart", 703, 12); |
+ $assert(this.definition == null, "definition == null", "type.dart", 747, 12); |
this.definition = def; |
if ((this.definition instanceof TypeDefinition) && this.definition.get$nativeType() != null) { |
this.isNativeType = true; |
@@ -20186,7 +20270,7 @@ DefinedType.prototype._resolveInterfaces = function(types) { |
return (interfaces && interfaces.is$List$Type()); |
} |
DefinedType.prototype.addDirectSubtype = function(type) { |
- $assert(this._subtypes == null, "_subtypes == null", "type.dart", 819, 12); |
+ $assert(this._subtypes == null, "_subtypes == null", "type.dart", 863, 12); |
this.directSubtypes.add(type); |
} |
DefinedType.prototype.get$subtypes = function() { |
@@ -20564,7 +20648,7 @@ DefinedType.prototype.resolveTypeParams = function(inType) { |
return this; |
} |
DefinedType.prototype.getOrMakeConcreteType = function(typeArgs) { |
- $assert(this.get$isGeneric(), "isGeneric", "type.dart", 1248, 12); |
+ $assert(this.get$isGeneric(), "isGeneric", "type.dart", 1292, 12); |
var names = [this.name]; |
var typeMap = $map([]); |
for (var i = 0; |
@@ -20582,7 +20666,7 @@ DefinedType.prototype.getOrMakeConcreteType = function(typeArgs) { |
return (ret && ret.is$lang_Type()); |
} |
DefinedType.prototype.getCallStub = function(args) { |
- $assert(this.get$isFunction(), "isFunction", "type.dart", 1268, 12); |
+ $assert(this.get$isFunction(), "isFunction", "type.dart", 1312, 12); |
var name = _getCallStubName('call', args); |
if (this.varStubs == null) this.varStubs = $map([]); |
var stub = this.varStubs.$index(name); |
@@ -21936,7 +22020,7 @@ VarMethodSet.prototype.invoke$4 = function($0, $1, $2, $3) { |
}; |
// ********** Code for top level ************** |
function map(source, mapper) { |
- var result = new ListFactory(); |
+ var result = []; |
if (!!(source && source.is$List)) { |
var list = (source && source.is$List()); |
result.length = list.length; |
@@ -21964,6 +22048,18 @@ function reduce(source, callback, initialValue) { |
} |
return current; |
} |
+function groupBy(left, keyFn) { |
+ var result = $map([]); |
+ var iter = left.iterator(); |
+ while ($notnull_bool(iter.hasNext$0())) { |
+ var i = iter.next$0(); |
+ result.putIfAbsent(keyFn(i), (function () { |
+ return []; |
+ }) |
+ ).add$1(i); |
+ } |
+ return result; |
+} |
function orderValuesByKeys(map) { |
var $0; |
var keys = (($0 = map.getKeys()) && $0.is$List()); |