소스 검색

Merge pull request #791 from herby/indexof-fix

Indexof fix
Nicolas Petton 11 년 전
부모
커밋
8cf1808a2a
6개의 변경된 파일207개의 추가작업 그리고 49개의 파일을 삭제
  1. 9 10
      js/Kernel-Collections.js
  2. 10 10
      js/Kernel-Objects.js
  3. 135 9
      js/Kernel-Tests.js
  4. 6 7
      st/Kernel-Collections.st
  5. 8 8
      st/Kernel-Objects.st
  6. 39 5
      st/Kernel-Tests.st

+ 9 - 10
js/Kernel-Collections.js

@@ -2795,13 +2795,13 @@ return smalltalk.withContext(function($ctx1) {
 
 		self = self._numericallyIndexable();
 		for(var i=0; i < self.length; i++) {
-			if(self[i].__eq(anObject)) {return i+1}
+			if(_st(self[i]).__eq(anObject)) {return i+1}
 		};
 		return aBlock._value();
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"indexOf:ifAbsent:",{anObject:anObject,aBlock:aBlock},smalltalk.SequenceableCollection)})},
 args: ["anObject", "aBlock"],
-source: "indexOf: anObject ifAbsent: aBlock\x0a\x09<\x0a\x09\x09self = self._numericallyIndexable();\x0a\x09\x09for(var i=0; i < self.length; i++) {\x0a\x09\x09\x09if(self[i].__eq(anObject)) {return i+1}\x0a\x09\x09};\x0a\x09\x09return aBlock._value();\x0a\x09>",
+source: "indexOf: anObject ifAbsent: aBlock\x0a\x09<\x0a\x09\x09self = self._numericallyIndexable();\x0a\x09\x09for(var i=0; i < self.length; i++) {\x0a\x09\x09\x09if(_st(self[i]).__eq(anObject)) {return i+1}\x0a\x09\x09};\x0a\x09\x09return aBlock._value();\x0a\x09>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -2838,13 +2838,13 @@ return smalltalk.withContext(function($ctx1) {
 
 		self = self._numericallyIndexable();
 		for(var i=start - 1; i < self.length; i++){
-			if(self[i].__eq(anObject)) {return i+1}
+			if(_st(self[i]).__eq(anObject)) {return i+1}
 		}
 		return aBlock._value();
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"indexOf:startingAt:ifAbsent:",{anObject:anObject,start:start,aBlock:aBlock},smalltalk.SequenceableCollection)})},
 args: ["anObject", "start", "aBlock"],
-source: "indexOf: anObject startingAt: start ifAbsent: aBlock\x0a\x09<\x0a\x09\x09self = self._numericallyIndexable();\x0a\x09\x09for(var i=start - 1; i < self.length; i++){\x0a\x09\x09\x09if(self[i].__eq(anObject)) {return i+1}\x0a\x09\x09}\x0a\x09\x09return aBlock._value();\x0a\x09>",
+source: "indexOf: anObject startingAt: start ifAbsent: aBlock\x0a\x09<\x0a\x09\x09self = self._numericallyIndexable();\x0a\x09\x09for(var i=start - 1; i < self.length; i++){\x0a\x09\x09\x09if(_st(self[i]).__eq(anObject)) {return i+1}\x0a\x09\x09}\x0a\x09\x09return aBlock._value();\x0a\x09>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -3983,15 +3983,14 @@ fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 
-		if(typeof aString === 'undefined') { return false }
-		if(!aString._isString || ! aString._isString()) {
-			return false;
-		}
-		return String(self) === String(aString)
+		return aString != null &&
+			typeof aString._isString === "function" &&
+			aString._isString() &&
+			String(self) === String(aString)
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"=",{aString:aString},smalltalk.String)})},
 args: ["aString"],
-source: "= aString\x0a\x09<\x0a\x09\x09if(typeof aString === 'undefined') { return false }\x0a\x09\x09if(!aString._isString || ! aString._isString()) {\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09\x09return String(self) === String(aString)\x0a\x09>",
+source: "= aString\x0a\x09<\x0a\x09\x09return aString != null &&\x0a\x09\x09\x09typeof aString._isString === \x22function\x22 &&\x0a\x09\x09\x09aString._isString() &&\x0a\x09\x09\x09String(self) === String(aString)\x0a\x09>",
 messageSends: [],
 referencedClasses: []
 }),

+ 10 - 10
js/Kernel-Objects.js

@@ -1302,14 +1302,14 @@ fn: function (aBoolean){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 
-		if(! aBoolean._isBoolean || ! aBoolean._isBoolean()) {
-			return false;
-		}
-		return Boolean(self == true) == aBoolean
+		return aBoolean != null &&
+			typeof aBoolean._isBoolean === "function" &&
+			aBoolean._isBoolean() &&
+			Boolean(self == true) == aBoolean
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"=",{aBoolean:aBoolean},smalltalk.Boolean)})},
 args: ["aBoolean"],
-source: "= aBoolean\x0a\x09<\x0a\x09\x09if(! aBoolean._isBoolean || ! aBoolean._isBoolean()) {\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09\x09return Boolean(self == true) == aBoolean\x0a\x09>",
+source: "= aBoolean\x0a\x09<\x0a\x09\x09return aBoolean != null &&\x0a\x09\x09\x09typeof aBoolean._isBoolean === \x22function\x22 &&\x0a\x09\x09\x09aBoolean._isBoolean() &&\x0a\x09\x09\x09Boolean(self == true) == aBoolean\x0a\x09>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -2474,14 +2474,14 @@ fn: function (aNumber){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 
-		if(! aNumber._isNumber || ! aNumber._isNumber()) {
-			return false;
-		}
-		return Number(self) == aNumber
+		return aNumber != null &&
+			typeof aNumber._isNumber === "function" &&
+			aNumber._isNumber() &&
+			Number(self) == aNumber
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"=",{aNumber:aNumber},smalltalk.Number)})},
 args: ["aNumber"],
-source: "= aNumber\x0a\x09<\x0a\x09\x09if(! aNumber._isNumber || ! aNumber._isNumber()) {\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09\x09return Number(self) == aNumber\x0a\x09>",
+source: "= aNumber\x0a\x09<\x0a\x09\x09return aNumber != null &&\x0a\x09\x09\x09typeof aNumber._isNumber === \x22function\x22 &&\x0a\x09\x09\x09aNumber._isNumber() &&\x0a\x09\x09\x09Number(self) == aNumber\x0a\x09>",
 messageSends: [],
 referencedClasses: []
 }),

+ 135 - 9
js/Kernel-Tests.js

@@ -2660,6 +2660,32 @@ referencedClasses: ["Error"]
 }),
 smalltalk.IndexableCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testIndexOfWithNull",
+protocol: 'tests',
+fn: function (){
+var self=this;
+var jsNull;
+function $JSON(){return smalltalk.JSON||(typeof JSON=="undefined"?nil:JSON)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+jsNull=_st($JSON())._parse_("null");
+self._samplesDo_((function(index,value){
+return smalltalk.withContext(function($ctx2) {
+$1=self._collection();
+_st($1)._at_put_(index,jsNull);
+$2=_st($1)._indexOf_(jsNull);
+return self._assert_equals_($2,index);
+}, function($ctx2) {$ctx2.fillBlock({index:index,value:value},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"testIndexOfWithNull",{jsNull:jsNull},smalltalk.IndexableCollectionTest)})},
+args: [],
+source: "testIndexOfWithNull\x0a\x09| jsNull |\x0a\x09jsNull := JSON parse: 'null'.\x0a\x09self samplesDo: [ :index :value |\x0a\x09\x09self assert: (self collection at: index put: jsNull; indexOf: jsNull) equals: index ]",
+messageSends: ["parse:", "samplesDo:", "assert:equals:", "at:put:", "collection", "indexOf:"],
+referencedClasses: ["JSON"]
+}),
+smalltalk.IndexableCollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testWithIndexDo",
@@ -3933,6 +3959,76 @@ referencedClasses: []
 }),
 smalltalk.SequenceableCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testIndexOfStartingAt",
+protocol: 'tests',
+fn: function (){
+var self=this;
+var jsNull;
+function $JSON(){return smalltalk.JSON||(typeof JSON=="undefined"?nil:JSON)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1,$4,$3;
+jsNull=_st($JSON())._parse_("null");
+self._samplesDo_((function(index,value){
+return smalltalk.withContext(function($ctx2) {
+$2=self._collection();
+$ctx2.sendIdx["collection"]=1;
+$1=_st($2)._indexOf_startingAt_(value,(1));
+$ctx2.sendIdx["indexOf:startingAt:"]=1;
+self._assert_equals_($1,index);
+$ctx2.sendIdx["assert:equals:"]=1;
+$4=self._collection();
+$ctx2.sendIdx["collection"]=2;
+$3=_st($4)._indexOf_startingAt_(value,index);
+$ctx2.sendIdx["indexOf:startingAt:"]=2;
+self._assert_equals_($3,index);
+$ctx2.sendIdx["assert:equals:"]=2;
+return self._assert_equals_(_st(self._collection())._indexOf_startingAt_(value,_st(index).__plus((1))),(0));
+}, function($ctx2) {$ctx2.fillBlock({index:index,value:value},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"testIndexOfStartingAt",{jsNull:jsNull},smalltalk.SequenceableCollectionTest)})},
+args: [],
+source: "testIndexOfStartingAt\x0a\x09| jsNull |\x0a\x09jsNull := JSON parse: 'null'.\x0a\x09self samplesDo: [ :index :value |\x0a\x09\x09self assert: (self collection indexOf: value startingAt: 1) equals: index.\x0a\x09\x09self assert: (self collection indexOf: value startingAt: index) equals: index.\x0a\x09\x09self assert: (self collection indexOf: value startingAt: index+1) equals: 0 ]",
+messageSends: ["parse:", "samplesDo:", "assert:equals:", "indexOf:startingAt:", "collection", "+"],
+referencedClasses: ["JSON"]
+}),
+smalltalk.SequenceableCollectionTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testIndexOfStartingAtWithNull",
+protocol: 'tests',
+fn: function (){
+var self=this;
+var jsNull;
+function $JSON(){return smalltalk.JSON||(typeof JSON=="undefined"?nil:JSON)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+jsNull=_st($JSON())._parse_("null");
+self._samplesDo_((function(index,value){
+var collection;
+return smalltalk.withContext(function($ctx2) {
+collection=self._collection();
+collection;
+_st(collection)._at_put_(index,jsNull);
+$1=_st(collection)._indexOf_startingAt_(jsNull,(1));
+$ctx2.sendIdx["indexOf:startingAt:"]=1;
+self._assert_equals_($1,index);
+$ctx2.sendIdx["assert:equals:"]=1;
+$2=_st(collection)._indexOf_startingAt_(jsNull,index);
+$ctx2.sendIdx["indexOf:startingAt:"]=2;
+self._assert_equals_($2,index);
+$ctx2.sendIdx["assert:equals:"]=2;
+return self._assert_equals_(_st(collection)._indexOf_startingAt_(jsNull,_st(index).__plus((1))),(0));
+}, function($ctx2) {$ctx2.fillBlock({index:index,value:value,collection:collection},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"testIndexOfStartingAtWithNull",{jsNull:jsNull},smalltalk.SequenceableCollectionTest)})},
+args: [],
+source: "testIndexOfStartingAtWithNull\x0a\x09| jsNull |\x0a\x09jsNull := JSON parse: 'null'.\x0a\x09self samplesDo: [ :index :value | | collection |\x0a\x09\x09collection := self collection.\x0a\x09\x09collection at: index put: jsNull.\x0a\x09\x09self assert: (collection indexOf: jsNull startingAt: 1) equals: index.\x0a\x09\x09self assert: (collection indexOf: jsNull startingAt: index) equals: index.\x0a\x09\x09self assert: (collection indexOf: jsNull startingAt: index+1) equals: 0 ]",
+messageSends: ["parse:", "samplesDo:", "collection", "at:put:", "assert:equals:", "indexOf:startingAt:", "+"],
+referencedClasses: ["JSON"]
+}),
+smalltalk.SequenceableCollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testLast",
@@ -4471,10 +4567,10 @@ protocol: 'fixture',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return "hello";
+return "helLo";
 }, function($ctx1) {$ctx1.fill(self,"collection",{},smalltalk.StringTest)})},
 args: [],
-source: "collection\x0a\x09^ 'hello'",
+source: "collection\x0a\x09^ 'helLo'",
 messageSends: [],
 referencedClasses: []
 }),
@@ -4535,10 +4631,10 @@ protocol: 'fixture',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return "lo";
+return "Lo";
 }, function($ctx1) {$ctx1.fill(self,"collectionLastTwo",{},smalltalk.StringTest)})},
 args: [],
-source: "collectionLastTwo\x0a\x09^ 'lo'",
+source: "collectionLastTwo\x0a\x09^ 'Lo'",
 messageSends: [],
 referencedClasses: []
 }),
@@ -4551,10 +4647,10 @@ protocol: 'fixture',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return "'h''e''l''l''o'";
+return "'h''e''l''L''o'";
 }, function($ctx1) {$ctx1.fill(self,"collectionOfPrintStrings",{},smalltalk.StringTest)})},
 args: [],
-source: "collectionOfPrintStrings\x0a\x09^ '''h''''e''''l''''l''''o'''",
+source: "collectionOfPrintStrings\x0a\x09^ '''h''''e''''l''''L''''o'''",
 messageSends: [],
 referencedClasses: []
 }),
@@ -4599,10 +4695,10 @@ protocol: 'fixture',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return "helloN";
+return "helLoN";
 }, function($ctx1) {$ctx1.fill(self,"collectionWithNewValue",{},smalltalk.StringTest)})},
 args: [],
-source: "collectionWithNewValue\x0a\x09^ 'helloN'",
+source: "collectionWithNewValue\x0a\x09^ 'helLoN'",
 messageSends: [],
 referencedClasses: []
 }),
@@ -4618,7 +4714,7 @@ return smalltalk.withContext(function($ctx1) {
 return "N";
 }, function($ctx1) {$ctx1.fill(self,"sampleNewValueAsCollection",{},smalltalk.StringTest)})},
 args: [],
-source: "sampleNewValueAsCollection\x0a\x09\x0a\x09^ 'N'",
+source: "sampleNewValueAsCollection\x0a\x09^ 'N'",
 messageSends: [],
 referencedClasses: []
 }),
@@ -5047,6 +5143,36 @@ referencedClasses: []
 }),
 smalltalk.StringTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testIndexOfStartingAtWithNull",
+protocol: 'tests',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self}, function($ctx1) {$ctx1.fill(self,"testIndexOfStartingAtWithNull",{},smalltalk.StringTest)})},
+args: [],
+source: "testIndexOfStartingAtWithNull\x0a\x09\x22String cannot hold JS null\x22",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.StringTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testIndexOfWithNull",
+protocol: 'tests',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self}, function($ctx1) {$ctx1.fill(self,"testIndexOfWithNull",{},smalltalk.StringTest)})},
+args: [],
+source: "testIndexOfWithNull\x0a\x09\x22String cannot hold JS null\x22",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.StringTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testIsVowel",

+ 6 - 7
st/Kernel-Collections.st

@@ -866,7 +866,7 @@ indexOf: anObject ifAbsent: aBlock
 	<
 		self = self._numericallyIndexable();
 		for(var i=0; i < self.length; i++) {
-			if(self[i].__eq(anObject)) {return i+1}
+			if(_st(self[i]).__eq(anObject)) {return i+1}
 		};
 		return aBlock._value();
 	>
@@ -883,7 +883,7 @@ indexOf: anObject startingAt: start ifAbsent: aBlock
 	<
 		self = self._numericallyIndexable();
 		for(var i=start - 1; i < self.length; i++){
-			if(self[i].__eq(anObject)) {return i+1}
+			if(_st(self[i]).__eq(anObject)) {return i+1}
 		}
 		return aBlock._value();
 	>
@@ -1383,11 +1383,10 @@ size
 
 = aString
 	<
-		if(typeof aString === 'undefined') { return false }
-		if(!!aString._isString || !! aString._isString()) {
-			return false;
-		}
-		return String(self) === String(aString)
+		return aString !!= null &&
+			typeof aString._isString === "function" &&
+			aString._isString() &&
+			String(self) === String(aString)
 	>
 !
 

+ 8 - 8
st/Kernel-Objects.st

@@ -440,10 +440,10 @@ I am directly mapped to JavaScript Boolean. The `true` and `false` objects are t
 
 = aBoolean
 	<
-		if(!! aBoolean._isBoolean || !! aBoolean._isBoolean()) {
-			return false;
-		}
-		return Boolean(self == true) == aBoolean
+		return aBoolean !!= null &&
+			typeof aBoolean._isBoolean === "function" &&
+			aBoolean._isBoolean() &&
+			Boolean(self == true) == aBoolean
 	>
 !
 
@@ -839,10 +839,10 @@ negated
 
 = aNumber
 	<
-		if(!! aNumber._isNumber || !! aNumber._isNumber()) {
-			return false;
-		}
-		return Number(self) == aNumber
+		return aNumber !!= null &&
+			typeof aNumber._isNumber === "function" &&
+			aNumber._isNumber() &&
+			Number(self) == aNumber
 	>
 !
 

+ 39 - 5
st/Kernel-Tests.st

@@ -734,6 +734,13 @@ testIndexOf
 		self assert: (self collection indexOf: value) equals: index ]
 !
 
+testIndexOfWithNull
+	| jsNull |
+	jsNull := JSON parse: 'null'.
+	self samplesDo: [ :index :value |
+		self assert: (self collection at: index put: jsNull; indexOf: jsNull) equals: index ]
+!
+
 testWithIndexDo
 	| collection |
 	collection := self collection.
@@ -1088,6 +1095,26 @@ testFourth
 	self assert: (self collection fourth) equals: (self collection at: 4)
 !
 
+testIndexOfStartingAt
+	| jsNull |
+	jsNull := JSON parse: 'null'.
+	self samplesDo: [ :index :value |
+		self assert: (self collection indexOf: value startingAt: 1) equals: index.
+		self assert: (self collection indexOf: value startingAt: index) equals: index.
+		self assert: (self collection indexOf: value startingAt: index+1) equals: 0 ]
+!
+
+testIndexOfStartingAtWithNull
+	| jsNull |
+	jsNull := JSON parse: 'null'.
+	self samplesDo: [ :index :value | | collection |
+		collection := self collection.
+		collection at: index put: jsNull.
+		self assert: (collection indexOf: jsNull startingAt: 1) equals: index.
+		self assert: (collection indexOf: jsNull startingAt: index) equals: index.
+		self assert: (collection indexOf: jsNull startingAt: index+1) equals: 0 ]
+!
+
 testLast
 	self assert: self collection last equals: self collectionLast
 !
@@ -1254,7 +1281,7 @@ SequenceableCollectionTest subclass: #StringTest
 !StringTest methodsFor: 'fixture'!
 
 collection
-	^ 'hello'
+	^ 'helLo'
 !
 
 collectionFirst
@@ -1270,11 +1297,11 @@ collectionLast
 !
 
 collectionLastTwo
-	^ 'lo'
+	^ 'Lo'
 !
 
 collectionOfPrintStrings
-	^ '''h''''e''''l''''l''''o'''
+	^ '''h''''e''''l''''L''''o'''
 !
 
 collectionSize
@@ -1286,11 +1313,10 @@ collectionWithDuplicates
 !
 
 collectionWithNewValue
-	^ 'helloN'
+	^ 'helLoN'
 !
 
 sampleNewValueAsCollection
-	
 	^ 'N'
 !
 
@@ -1410,6 +1436,14 @@ testIncludesSubString
 	self deny: ('amber' includesSubString: 'zork').
 !
 
+testIndexOfStartingAtWithNull
+	"String cannot hold JS null"
+!
+
+testIndexOfWithNull
+	"String cannot hold JS null"
+!
+
 testIsVowel
     |vowel consonant|
     vowel := 'u'.