Browse Source

Merge branch 'hashed-collection-fixes' of https://github.com/kpullen/amber

Conflicts:
	js/Kernel-Collections.deploy.js
	js/Kernel-Collections.js
Nicolas Petton 11 years ago
parent
commit
62c73a8d5d

+ 48 - 5
js/Kernel-Collections.deploy.js

@@ -879,10 +879,10 @@ var self=this;
 function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st($Dictionary())._fromPairs_(self._associations());
+$1=_st($Dictionary())._from_(_st(self)._associations());
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asDictionary",{},smalltalk.HashedCollection)})},
-messageSends: ["fromPairs:", "associations"]}),
+messageSends: ["from:", "associations"]}),
 smalltalk.HashedCollection);
 
 smalltalk.addMethod(
@@ -1311,6 +1311,25 @@ messageSends: ["keysAndValuesDo:", "value:value:"]}),
 smalltalk.HashedCollection);
 
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "from:",
+fn: function (aCollection){
+var self=this;
+var newCollection;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+newCollection=_st(self)._new();
+_st(aCollection)._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(newCollection)._add_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+$1=newCollection;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"from:",{aCollection:aCollection,newCollection:newCollection},smalltalk.HashedCollection.klass)})},
+messageSends: ["new", "do:", "add:"]}),
+smalltalk.HashedCollection.klass);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "fromPairs:",
@@ -1319,6 +1338,7 @@ var self=this;
 var dict;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
+_st(self)._deprecatedAPI();
 dict=self._new();
 _st(aCollection)._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
@@ -1327,7 +1347,30 @@ return _st(dict)._add_(each);
 $1=dict;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"fromPairs:",{aCollection:aCollection,dict:dict},smalltalk.HashedCollection.klass)})},
-messageSends: ["new", "do:", "add:"]}),
+messageSends: ["deprecatedAPI", "new", "do:", "add:"]}),
+smalltalk.HashedCollection.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "newFromPairs:",
+fn: function (aCollection){
+var self=this;
+var newCollection;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(_st(aCollection)._size())._even();
+if(! smalltalk.assert($1)){
+_st(self)._error_("#newFromPairs only accepts arrays of an even length");
+};
+newCollection=_st(self)._new();
+_st(_st((1))._to_by_(_st(aCollection)._size(),(2)))._do_((function(keyIndex){
+return smalltalk.withContext(function($ctx2) {
+return _st(newCollection)._at_put_(_st(aCollection)._at_(keyIndex),_st(aCollection)._at_(_st(keyIndex).__plus((1))));
+}, function($ctx2) {$ctx2.fillBlock({keyIndex:keyIndex},$ctx1)})}));
+$2=newCollection;
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"newFromPairs:",{aCollection:aCollection,newCollection:newCollection},smalltalk.HashedCollection.klass)})},
+messageSends: ["ifFalse:", "error:", "even", "size", "new", "do:", "at:put:", "at:", "+", "to:by:"]}),
 smalltalk.HashedCollection.klass);
 
 
@@ -1340,10 +1383,10 @@ var self=this;
 function $HashedCollection(){return smalltalk.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st($HashedCollection())._fromPairs_(self._associations());
+$1=_st($HashedCollection())._from_(_st(self)._associations());
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asHashedCollection",{},smalltalk.Dictionary)})},
-messageSends: ["fromPairs:", "associations"]}),
+messageSends: ["from:", "associations"]}),
 smalltalk.Dictionary);
 
 smalltalk.addMethod(

+ 61 - 8
js/Kernel-Collections.js

@@ -1169,12 +1169,12 @@ var self=this;
 function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st($Dictionary())._fromPairs_(self._associations());
+$1=_st($Dictionary())._from_(_st(self)._associations());
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asDictionary",{},smalltalk.HashedCollection)})},
 args: [],
-source: "asDictionary\x0a\x09^Dictionary fromPairs: self associations",
-messageSends: ["fromPairs:", "associations"],
+source: "asDictionary\x0a\x09^Dictionary from: self associations",
+messageSends: ["from:", "associations"],
 referencedClasses: ["Dictionary"]
 }),
 smalltalk.HashedCollection);
@@ -1740,6 +1740,30 @@ referencedClasses: []
 smalltalk.HashedCollection);
 
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "from:",
+category: 'instance creation',
+fn: function (aCollection){
+var self=this;
+var newCollection;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+newCollection=_st(self)._new();
+_st(aCollection)._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(newCollection)._add_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+$1=newCollection;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"from:",{aCollection:aCollection,newCollection:newCollection},smalltalk.HashedCollection.klass)})},
+args: ["aCollection"],
+source: "from: aCollection\x0a| newCollection |\x0anewCollection := self new.\x0aaCollection do: [:each | newCollection add: each].\x0a^ newCollection.",
+messageSends: ["new", "do:", "add:"],
+referencedClasses: []
+}),
+smalltalk.HashedCollection.klass);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "fromPairs:",
@@ -1749,6 +1773,7 @@ var self=this;
 var dict;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
+_st(self)._deprecatedAPI();
 dict=self._new();
 _st(aCollection)._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
@@ -1758,8 +1783,36 @@ $1=dict;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"fromPairs:",{aCollection:aCollection,dict:dict},smalltalk.HashedCollection.klass)})},
 args: ["aCollection"],
-source: "fromPairs: aCollection\x0a\x09| dict |\x0a\x09dict := self new.\x0a\x09aCollection do: [:each | dict add: each].\x0a\x09^dict",
-messageSends: ["new", "do:", "add:"],
+source: "fromPairs: aCollection\x0a\x09\x22This message is poorly named and has been replaced by #newFrom:\x22\x0a\x09| dict |\x0a\x09self deprecatedAPI.\x0a\x09dict := self new.\x0a\x09aCollection do: [:each | dict add: each].\x0a\x09^dict",
+messageSends: ["deprecatedAPI", "new", "do:", "add:"],
+referencedClasses: []
+}),
+smalltalk.HashedCollection.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "newFromPairs:",
+category: 'instance creation',
+fn: function (aCollection){
+var self=this;
+var newCollection;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(_st(aCollection)._size())._even();
+if(! smalltalk.assert($1)){
+_st(self)._error_("#newFromPairs only accepts arrays of an even length");
+};
+newCollection=_st(self)._new();
+_st(_st((1))._to_by_(_st(aCollection)._size(),(2)))._do_((function(keyIndex){
+return smalltalk.withContext(function($ctx2) {
+return _st(newCollection)._at_put_(_st(aCollection)._at_(keyIndex),_st(aCollection)._at_(_st(keyIndex).__plus((1))));
+}, function($ctx2) {$ctx2.fillBlock({keyIndex:keyIndex},$ctx1)})}));
+$2=newCollection;
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"newFromPairs:",{aCollection:aCollection,newCollection:newCollection},smalltalk.HashedCollection.klass)})},
+args: ["aCollection"],
+source: "newFromPairs: aCollection\x0a\x22Accept an array of elements where every two elements form an association - the odd element being the key, and the even element the value.\x22\x0a| newCollection |\x0aaCollection size even ifFalse: [ self error: '#newFromPairs only accepts arrays of an even length' ].\x0anewCollection := self new.\x0a( 1 to: aCollection size by: 2 ) do: [ :keyIndex | newCollection at: ( aCollection at: keyIndex ) put: ( aCollection at: keyIndex + 1 ) ].\x0a^ newCollection.",
+messageSends: ["ifFalse:", "error:", "even", "size", "new", "do:", "at:put:", "at:", "+", "to:by:"],
 referencedClasses: []
 }),
 smalltalk.HashedCollection.klass);
@@ -1776,12 +1829,12 @@ var self=this;
 function $HashedCollection(){return smalltalk.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st($HashedCollection())._fromPairs_(self._associations());
+$1=_st($HashedCollection())._from_(_st(self)._associations());
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asHashedCollection",{},smalltalk.Dictionary)})},
 args: [],
-source: "asHashedCollection\x0a\x09^HashedCollection fromPairs: self associations",
-messageSends: ["fromPairs:", "associations"],
+source: "asHashedCollection\x0a\x09^HashedCollection from: self associations",
+messageSends: ["from:", "associations"],
 referencedClasses: ["HashedCollection"]
 }),
 smalltalk.Dictionary);

+ 50 - 0
js/Kernel-Tests.deploy.js

@@ -1080,6 +1080,18 @@ return $1;
 messageSends: ["->"]}),
 smalltalk.HashedCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testAsDictionary",
+fn: function (){
+var self=this;
+function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
+return smalltalk.withContext(function($ctx1) { 
+_st(self)._assert_(_st(_st(_st(_st(self)._collectionClass())._new())._asDictionary())._isMemberOf_($Dictionary()));
+return self}, function($ctx1) {$ctx1.fill(self,"testAsDictionary",{},smalltalk.HashedCollectionTest)})},
+messageSends: ["assert:", "isMemberOf:", "asDictionary", "new", "collectionClass"]}),
+smalltalk.HashedCollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testAt",
@@ -1117,6 +1129,19 @@ return self}, function($ctx1) {$ctx1.fill(self,"testContains",{collection:collec
 messageSends: ["collection", "assert:", "contains:", "=", "first", "values", "deny:", "new"]}),
 smalltalk.HashedCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testFrom",
+fn: function (){
+var self=this;
+var associations;
+return smalltalk.withContext(function($ctx1) { 
+associations=[_st("a").__minus_gt((1)),_st("b").__minus_gt((2))];
+_st(self)._assertSameContents_as_(_st(_st(_st(self)._class())._collectionClass())._from_(associations),smalltalk.HashedCollection._fromPairs_([_st("a").__minus_gt((1)),_st("b").__minus_gt((2))]));
+return self}, function($ctx1) {$ctx1.fill(self,"testFrom",{associations:associations},smalltalk.HashedCollectionTest)})},
+messageSends: ["->", "assertSameContents:as:", "from:", "collectionClass", "class"]}),
+smalltalk.HashedCollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testIndexOf",
@@ -1137,6 +1162,19 @@ return self}, function($ctx1) {$ctx1.fill(self,"testIndexOf",{},smalltalk.Hashed
 messageSends: ["assert:equals:", "indexOf:", "collection", "should:raise:", "indexOf:ifAbsent:"]}),
 smalltalk.HashedCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testNewFromPairs",
+fn: function (){
+var self=this;
+var flattenedAssociations;
+return smalltalk.withContext(function($ctx1) { 
+flattenedAssociations=["a",(1),"b",(2)];
+_st(self)._assertSameContents_as_(_st(_st(_st(self)._class())._collectionClass())._newFromPairs_(flattenedAssociations),smalltalk.HashedCollection._fromPairs_([_st("a").__minus_gt((1)),_st("b").__minus_gt((2))]));
+return self}, function($ctx1) {$ctx1.fill(self,"testNewFromPairs",{flattenedAssociations:flattenedAssociations},smalltalk.HashedCollectionTest)})},
+messageSends: ["assertSameContents:as:", "newFromPairs:", "collectionClass", "class", "->"]}),
+smalltalk.HashedCollectionTest);
+
 
 smalltalk.addMethod(
 smalltalk.method({
@@ -1228,6 +1266,18 @@ return self}, function($ctx1) {$ctx1.fill(self,"testAccessing",{d:d},smalltalk.D
 messageSends: ["new", "at:put:", "assert:equals:", "at:", "at:ifAbsent:", "deny:", "=", "assert:", "includesKey:", "@"]}),
 smalltalk.DictionaryTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testAsHashedCollection",
+fn: function (){
+var self=this;
+function $HashedCollection(){return smalltalk.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
+return smalltalk.withContext(function($ctx1) { 
+_st(self)._assert_(_st(_st(_st(_st(self)._collectionClass())._new())._asHashedCollection())._isMemberOf_($HashedCollection()));
+return self}, function($ctx1) {$ctx1.fill(self,"testAsHashedCollection",{},smalltalk.DictionaryTest)})},
+messageSends: ["assert:", "isMemberOf:", "asHashedCollection", "new", "collectionClass"]}),
+smalltalk.DictionaryTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testDynamicDictionaries",

+ 70 - 0
js/Kernel-Tests.js

@@ -1340,6 +1340,23 @@ referencedClasses: []
 }),
 smalltalk.HashedCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testAsDictionary",
+category: 'tests',
+fn: function (){
+var self=this;
+function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
+return smalltalk.withContext(function($ctx1) { 
+_st(self)._assert_(_st(_st(_st(_st(self)._collectionClass())._new())._asDictionary())._isMemberOf_($Dictionary()));
+return self}, function($ctx1) {$ctx1.fill(self,"testAsDictionary",{},smalltalk.HashedCollectionTest)})},
+args: [],
+source: "testAsDictionary\x0aself assert: ( self collectionClass new asDictionary isMemberOf: Dictionary ).",
+messageSends: ["assert:", "isMemberOf:", "asDictionary", "new", "collectionClass"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.HashedCollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testAt",
@@ -1387,6 +1404,24 @@ referencedClasses: ["Object"]
 }),
 smalltalk.HashedCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testFrom",
+category: 'tests',
+fn: function (){
+var self=this;
+var associations;
+return smalltalk.withContext(function($ctx1) { 
+associations=[_st("a").__minus_gt((1)),_st("b").__minus_gt((2))];
+_st(self)._assertSameContents_as_(_st(_st(_st(self)._class())._collectionClass())._from_(associations),smalltalk.HashedCollection._fromPairs_([_st("a").__minus_gt((1)),_st("b").__minus_gt((2))]));
+return self}, function($ctx1) {$ctx1.fill(self,"testFrom",{associations:associations},smalltalk.HashedCollectionTest)})},
+args: [],
+source: "testFrom\x0a\x22Accept a collection of associations.\x22\x0a| associations |\x0aassociations := { 'a' -> 1. 'b' -> 2 }.\x0aself assertSameContents: ( self class collectionClass from: associations ) as: #{ 'a' -> 1. 'b' -> 2 }.",
+messageSends: ["->", "assertSameContents:as:", "from:", "collectionClass", "class"],
+referencedClasses: []
+}),
+smalltalk.HashedCollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testIndexOf",
@@ -1412,6 +1447,24 @@ referencedClasses: ["Error"]
 }),
 smalltalk.HashedCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testNewFromPairs",
+category: 'tests',
+fn: function (){
+var self=this;
+var flattenedAssociations;
+return smalltalk.withContext(function($ctx1) { 
+flattenedAssociations=["a",(1),"b",(2)];
+_st(self)._assertSameContents_as_(_st(_st(_st(self)._class())._collectionClass())._newFromPairs_(flattenedAssociations),smalltalk.HashedCollection._fromPairs_([_st("a").__minus_gt((1)),_st("b").__minus_gt((2))]));
+return self}, function($ctx1) {$ctx1.fill(self,"testNewFromPairs",{flattenedAssociations:flattenedAssociations},smalltalk.HashedCollectionTest)})},
+args: [],
+source: "testNewFromPairs\x0a\x22Accept an array in which all odd indexes are keys and evens are values.\x22\x0a| flattenedAssociations |\x0aflattenedAssociations := { 'a'. 1. 'b'. 2 }.\x0aself assertSameContents: ( self class collectionClass newFromPairs: flattenedAssociations ) as: #{ 'a' -> 1. 'b' -> 2 }.",
+messageSends: ["assertSameContents:as:", "newFromPairs:", "collectionClass", "class", "->"],
+referencedClasses: []
+}),
+smalltalk.HashedCollectionTest);
+
 
 smalltalk.addMethod(
 smalltalk.method({
@@ -1523,6 +1576,23 @@ referencedClasses: ["Dictionary"]
 }),
 smalltalk.DictionaryTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testAsHashedCollection",
+category: 'tests',
+fn: function (){
+var self=this;
+function $HashedCollection(){return smalltalk.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
+return smalltalk.withContext(function($ctx1) { 
+_st(self)._assert_(_st(_st(_st(_st(self)._collectionClass())._new())._asHashedCollection())._isMemberOf_($HashedCollection()));
+return self}, function($ctx1) {$ctx1.fill(self,"testAsHashedCollection",{},smalltalk.DictionaryTest)})},
+args: [],
+source: "testAsHashedCollection\x0aself assert: ( self collectionClass new asHashedCollection isMemberOf: HashedCollection ).",
+messageSends: ["assert:", "isMemberOf:", "asHashedCollection", "new", "collectionClass"],
+referencedClasses: ["HashedCollection"]
+}),
+smalltalk.DictionaryTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testDynamicDictionaries",

+ 20 - 2
st/Kernel-Collections.st

@@ -473,7 +473,7 @@ removeKey: aKey ifAbsent: aBlock
 !HashedCollection methodsFor: 'converting'!
 
 asDictionary
-	^Dictionary fromPairs: self associations
+	^Dictionary from: self associations
 !
 
 asJSON
@@ -578,11 +578,29 @@ includesKey: aKey
 
 !HashedCollection class methodsFor: 'instance creation'!
 
+from: aCollection
+| newCollection |
+newCollection := self new.
+aCollection do: [:each | newCollection add: each].
+^ newCollection.
+!
+
 fromPairs: aCollection
+	"This message is poorly named and has been replaced by #newFrom:"
 	| dict |
+	self deprecatedAPI.
 	dict := self new.
 	aCollection do: [:each | dict add: each].
 	^dict
+!
+
+newFromPairs: aCollection
+"Accept an array of elements where every two elements form an association - the odd element being the key, and the even element the value."
+| newCollection |
+aCollection size even ifFalse: [ self error: '#newFromPairs only accepts arrays of an even length' ].
+newCollection := self new.
+( 1 to: aCollection size by: 2 ) do: [ :keyIndex | newCollection at: ( aCollection at: keyIndex ) put: ( aCollection at: keyIndex + 1 ) ].
+^ newCollection.
 ! !
 
 HashedCollection subclass: #Dictionary
@@ -653,7 +671,7 @@ removeKey: aKey ifAbsent: aBlock
 !Dictionary methodsFor: 'converting'!
 
 asHashedCollection
-	^HashedCollection fromPairs: self associations
+	^HashedCollection from: self associations
 !
 
 asJSON

+ 22 - 0
st/Kernel-Tests.st

@@ -490,6 +490,10 @@ collectionWithDuplicates
 
 !HashedCollectionTest methodsFor: 'tests'!
 
+testAsDictionary
+self assert: ( self collectionClass new asDictionary isMemberOf: Dictionary ).
+!
+
 testAt
 	self assert: (self collection at: 'a') equals: 2.
 	self should: [ self collection at: 5 ] raise: Error
@@ -503,10 +507,24 @@ testContains
 	self deny: (self collection contains: [ :each | each = Object new ])
 !
 
+testFrom
+"Accept a collection of associations."
+| associations |
+associations := { 'a' -> 1. 'b' -> 2 }.
+self assertSameContents: ( self class collectionClass from: associations ) as: #{ 'a' -> 1. 'b' -> 2 }.
+!
+
 testIndexOf
 	self assert: (self collection indexOf: 2) equals: 'a'.
 	self should: [ self collection indexOf: 999 ] raise: Error.
 	self assert: (self collection indexOf: 999 ifAbsent: [ 'sentinel' ]) equals: 'sentinel'
+!
+
+testNewFromPairs
+"Accept an array in which all odd indexes are keys and evens are values."
+| flattenedAssociations |
+flattenedAssociations := { 'a'. 1. 'b'. 2 }.
+self assertSameContents: ( self class collectionClass newFromPairs: flattenedAssociations ) as: #{ 'a' -> 1. 'b' -> 2 }.
 ! !
 
 !HashedCollectionTest class methodsFor: 'accessing'!
@@ -567,6 +585,10 @@ testAccessing
 	self deny: (d includesKey: 3@1)
 !
 
+testAsHashedCollection
+self assert: ( self collectionClass new asHashedCollection isMemberOf: HashedCollection ).
+!
+
 testDynamicDictionaries
 	self assert: #{'hello' -> 1} asDictionary equals: (Dictionary with: 'hello' -> 1)
 !