Sfoglia il codice sorgente

Extract TNativeZeroBasedCollection.

Herby Vojčík 6 anni fa
parent
commit
1f994690a3
2 ha cambiato i file con 279 aggiunte e 235 eliminazioni
  1. 207 178
      lang/src/Kernel-Collections.js
  2. 72 57
      lang/src/Kernel-Collections.st

+ 207 - 178
lang/src/Kernel-Collections.js

@@ -4092,63 +4092,6 @@ messageSends: ["subclassResponsibility"]
 }),
 }),
 $globals.SequenceableCollection);
 $globals.SequenceableCollection);
 
 
-$core.addMethod(
-$core.method({
-selector: "detect:ifNone:",
-protocol: "enumerating",
-fn: function (aBlock,anotherBlock){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-
-		for(var i = 0; i < self.length; i++)
-			if(aBlock._value_(self[i]))
-				return self[i];
-		return anotherBlock._value();
-	;
-return self;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"detect:ifNone:",{aBlock:aBlock,anotherBlock:anotherBlock},$globals.SequenceableCollection)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aBlock", "anotherBlock"],
-source: "detect: aBlock ifNone: anotherBlock\x0a\x09<inlineJS: '\x0a\x09\x09for(var i = 0; i < self.length; i++)\x0a\x09\x09\x09if(aBlock._value_(self[i]))\x0a\x09\x09\x09\x09return self[i];\x0a\x09\x09return anotherBlock._value();\x0a\x09'>",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.SequenceableCollection);
-
-$core.addMethod(
-$core.method({
-selector: "do:",
-protocol: "enumerating",
-fn: function (aBlock){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-
-		for(var i=0; i < self.length; i++) {
-			aBlock._value_(self[i]);
-		}
-	;
-return self;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"do:",{aBlock:aBlock},$globals.SequenceableCollection)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aBlock"],
-source: "do: aBlock\x0a\x09<inlineJS: '\x0a\x09\x09for(var i=0; i < self.length; i++) {\x0a\x09\x09\x09aBlock._value_(self[i]);\x0a\x09\x09}\x0a\x09'>",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.SequenceableCollection);
-
 $core.addMethod(
 $core.addMethod(
 $core.method({
 $core.method({
 selector: "endsWith:",
 selector: "endsWith:",
@@ -4285,35 +4228,6 @@ messageSends: ["notNil", "indexOf:ifAbsent:"]
 }),
 }),
 $globals.SequenceableCollection);
 $globals.SequenceableCollection);
 
 
-$core.addMethod(
-$core.method({
-selector: "indexOf:ifAbsent:",
-protocol: "accessing",
-fn: function (anObject,aBlock){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-
-		for(var i=0; i < self.length; i++) {
-			if($recv(self[i]).__eq(anObject)) {return i+1}
-		};
-		return aBlock._value();
-	;
-return self;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"indexOf:ifAbsent:",{anObject:anObject,aBlock:aBlock},$globals.SequenceableCollection)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["anObject", "aBlock"],
-source: "indexOf: anObject ifAbsent: aBlock\x0a\x09<inlineJS: '\x0a\x09\x09for(var i=0; i < self.length; i++) {\x0a\x09\x09\x09if($recv(self[i]).__eq(anObject)) {return i+1}\x0a\x09\x09};\x0a\x09\x09return aBlock._value();\x0a\x09'>",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.SequenceableCollection);
-
 $core.addMethod(
 $core.addMethod(
 $core.method({
 $core.method({
 selector: "indexOf:startingAt:",
 selector: "indexOf:startingAt:",
@@ -4349,12 +4263,7 @@ var self=this,$self=this;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-
-		for(var i=start - 1; i < self.length; i++){
-			if($recv(self[i]).__eq(anObject)) {return i+1}
-		}
-		return aBlock._value();
-	;
+$self._subclassResponsibility();
 return self;
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 }, function($ctx1) {$ctx1.fill(self,"indexOf:startingAt:ifAbsent:",{anObject:anObject,start:start,aBlock:aBlock},$globals.SequenceableCollection)});
 }, function($ctx1) {$ctx1.fill(self,"indexOf:startingAt:ifAbsent:",{anObject:anObject,start:start,aBlock:aBlock},$globals.SequenceableCollection)});
@@ -4362,10 +4271,10 @@ return self;
 },
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["anObject", "start", "aBlock"],
 args: ["anObject", "start", "aBlock"],
-source: "indexOf: anObject startingAt: start ifAbsent: aBlock\x0a\x09<inlineJS: '\x0a\x09\x09for(var i=start - 1; i < self.length; i++){\x0a\x09\x09\x09if($recv(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\x09self subclassResponsibility",
 referencedClasses: [],
 referencedClasses: [],
 //>>excludeEnd("ide");
 //>>excludeEnd("ide");
-messageSends: []
+messageSends: ["subclassResponsibility"]
 }),
 }),
 $globals.SequenceableCollection);
 $globals.SequenceableCollection);
 
 
@@ -4570,33 +4479,6 @@ messageSends: ["at:"]
 }),
 }),
 $globals.SequenceableCollection);
 $globals.SequenceableCollection);
 
 
-$core.addMethod(
-$core.method({
-selector: "single",
-protocol: "accessing",
-fn: function (){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-
-	if (self.length == 0) throw new Error("Collection is empty");
-	if (self.length > 1) throw new Error("Collection holds more than one element.");
-	return self[0];;
-return self;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"single",{},$globals.SequenceableCollection)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: [],
-source: "single\x0a<inlineJS: '\x0a\x09if (self.length == 0) throw new Error(\x22Collection is empty\x22);\x0a\x09if (self.length > 1) throw new Error(\x22Collection holds more than one element.\x22);\x0a\x09return self[0];\x0a'>",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.SequenceableCollection);
-
 $core.addMethod(
 $core.addMethod(
 $core.method({
 $core.method({
 selector: "stream",
 selector: "stream",
@@ -4666,63 +4548,6 @@ messageSends: ["at:"]
 }),
 }),
 $globals.SequenceableCollection);
 $globals.SequenceableCollection);
 
 
-$core.addMethod(
-$core.method({
-selector: "with:do:",
-protocol: "enumerating",
-fn: function (anotherCollection,aBlock){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-
-	    $recv(anotherCollection)._first_(0); // #guardSequenceableCollection
-		for(var i=0; i<self.length; i++) {
-			aBlock._value_value_(self[i], anotherCollection[i]);
-		}
-	;
-return self;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"with:do:",{anotherCollection:anotherCollection,aBlock:aBlock},$globals.SequenceableCollection)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["anotherCollection", "aBlock"],
-source: "with: anotherCollection do: aBlock\x0a\x09<inlineJS: '\x0a\x09    $recv(anotherCollection)._first_(0); // #guardSequenceableCollection\x0a\x09\x09for(var i=0; i<self.length; i++) {\x0a\x09\x09\x09aBlock._value_value_(self[i], anotherCollection[i]);\x0a\x09\x09}\x0a\x09'>",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.SequenceableCollection);
-
-$core.addMethod(
-$core.method({
-selector: "withIndexDo:",
-protocol: "enumerating",
-fn: function (aBlock){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-
-		for(var i=0; i < self.length; i++) {
-			aBlock._value_value_(self[i], i+1);
-		}
-	;
-return self;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"withIndexDo:",{aBlock:aBlock},$globals.SequenceableCollection)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aBlock"],
-source: "withIndexDo: aBlock\x0a\x09<inlineJS: '\x0a\x09\x09for(var i=0; i < self.length; i++) {\x0a\x09\x09\x09aBlock._value_value_(self[i], i+1);\x0a\x09\x09}\x0a\x09'>",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.SequenceableCollection);
-
 $core.addMethod(
 $core.addMethod(
 $core.method({
 $core.method({
 selector: "writeStream",
 selector: "writeStream",
@@ -10085,4 +9910,208 @@ messageSends: []
 }),
 }),
 $globals.RegularExpression.a$cls);
 $globals.RegularExpression.a$cls);
 
 
+
+$core.addTrait("TNativeZeroBasedCollection", "Kernel-Collections");
+$core.addMethod(
+$core.method({
+selector: "detect:ifNone:",
+protocol: "enumerating",
+fn: function (aBlock,anotherBlock){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+
+		for(var i = 0; i < self.length; i++)
+			if(aBlock._value_(self[i]))
+				return self[i];
+		return anotherBlock._value();
+	;
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"detect:ifNone:",{aBlock:aBlock,anotherBlock:anotherBlock},$globals.TNativeZeroBasedCollection)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aBlock", "anotherBlock"],
+source: "detect: aBlock ifNone: anotherBlock\x0a\x09<inlineJS: '\x0a\x09\x09for(var i = 0; i < self.length; i++)\x0a\x09\x09\x09if(aBlock._value_(self[i]))\x0a\x09\x09\x09\x09return self[i];\x0a\x09\x09return anotherBlock._value();\x0a\x09'>",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.TNativeZeroBasedCollection);
+
+$core.addMethod(
+$core.method({
+selector: "do:",
+protocol: "enumerating",
+fn: function (aBlock){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+
+		for(var i=0; i < self.length; i++) {
+			aBlock._value_(self[i]);
+		}
+	;
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"do:",{aBlock:aBlock},$globals.TNativeZeroBasedCollection)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aBlock"],
+source: "do: aBlock\x0a\x09<inlineJS: '\x0a\x09\x09for(var i=0; i < self.length; i++) {\x0a\x09\x09\x09aBlock._value_(self[i]);\x0a\x09\x09}\x0a\x09'>",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.TNativeZeroBasedCollection);
+
+$core.addMethod(
+$core.method({
+selector: "indexOf:ifAbsent:",
+protocol: "accessing",
+fn: function (anObject,aBlock){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+
+		for(var i=0; i < self.length; i++) {
+			if($recv(self[i]).__eq(anObject)) {return i+1}
+		};
+		return aBlock._value();
+	;
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"indexOf:ifAbsent:",{anObject:anObject,aBlock:aBlock},$globals.TNativeZeroBasedCollection)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anObject", "aBlock"],
+source: "indexOf: anObject ifAbsent: aBlock\x0a\x09<inlineJS: '\x0a\x09\x09for(var i=0; i < self.length; i++) {\x0a\x09\x09\x09if($recv(self[i]).__eq(anObject)) {return i+1}\x0a\x09\x09};\x0a\x09\x09return aBlock._value();\x0a\x09'>",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.TNativeZeroBasedCollection);
+
+$core.addMethod(
+$core.method({
+selector: "indexOf:startingAt:ifAbsent:",
+protocol: "accessing",
+fn: function (anObject,start,aBlock){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+
+		for(var i=start - 1; i < self.length; i++){
+			if($recv(self[i]).__eq(anObject)) {return i+1}
+		}
+		return aBlock._value();
+	;
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"indexOf:startingAt:ifAbsent:",{anObject:anObject,start:start,aBlock:aBlock},$globals.TNativeZeroBasedCollection)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anObject", "start", "aBlock"],
+source: "indexOf: anObject startingAt: start ifAbsent: aBlock\x0a\x09<inlineJS: '\x0a\x09\x09for(var i=start - 1; i < self.length; i++){\x0a\x09\x09\x09if($recv(self[i]).__eq(anObject)) {return i+1}\x0a\x09\x09}\x0a\x09\x09return aBlock._value();\x0a\x09'>",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.TNativeZeroBasedCollection);
+
+$core.addMethod(
+$core.method({
+selector: "single",
+protocol: "accessing",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+
+	if (self.length == 0) throw new Error("Collection is empty");
+	if (self.length > 1) throw new Error("Collection holds more than one element.");
+	return self[0];;
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"single",{},$globals.TNativeZeroBasedCollection)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "single\x0a<inlineJS: '\x0a\x09if (self.length == 0) throw new Error(\x22Collection is empty\x22);\x0a\x09if (self.length > 1) throw new Error(\x22Collection holds more than one element.\x22);\x0a\x09return self[0];\x0a'>",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.TNativeZeroBasedCollection);
+
+$core.addMethod(
+$core.method({
+selector: "with:do:",
+protocol: "enumerating",
+fn: function (anotherCollection,aBlock){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+
+	    $recv(anotherCollection)._first_(0); // #guardSequenceableCollection
+		for(var i=0; i<self.length; i++) {
+			aBlock._value_value_(self[i], anotherCollection[i]);
+		}
+	;
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"with:do:",{anotherCollection:anotherCollection,aBlock:aBlock},$globals.TNativeZeroBasedCollection)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anotherCollection", "aBlock"],
+source: "with: anotherCollection do: aBlock\x0a\x09<inlineJS: '\x0a\x09    $recv(anotherCollection)._first_(0); // #guardSequenceableCollection\x0a\x09\x09for(var i=0; i<self.length; i++) {\x0a\x09\x09\x09aBlock._value_value_(self[i], anotherCollection[i]);\x0a\x09\x09}\x0a\x09'>",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.TNativeZeroBasedCollection);
+
+$core.addMethod(
+$core.method({
+selector: "withIndexDo:",
+protocol: "enumerating",
+fn: function (aBlock){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+
+		for(var i=0; i < self.length; i++) {
+			aBlock._value_value_(self[i], i+1);
+		}
+	;
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"withIndexDo:",{aBlock:aBlock},$globals.TNativeZeroBasedCollection)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aBlock"],
+source: "withIndexDo: aBlock\x0a\x09<inlineJS: '\x0a\x09\x09for(var i=0; i < self.length; i++) {\x0a\x09\x09\x09aBlock._value_value_(self[i], i+1);\x0a\x09\x09}\x0a\x09'>",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.TNativeZeroBasedCollection);
+
+$core.setTraitComposition([{trait: $globals.TNativeZeroBasedCollection}], $globals.Array);
+$core.setTraitComposition([{trait: $globals.TNativeZeroBasedCollection}], $globals.String);
+
 });
 });

+ 72 - 57
lang/src/Kernel-Collections.st

@@ -989,15 +989,6 @@ fourth
 	^ self at: 4
 	^ self at: 4
 !
 !
 
 
-indexOf: anObject ifAbsent: aBlock
-	<inlineJS: '
-		for(var i=0; i < self.length; i++) {
-			if($recv(self[i]).__eq(anObject)) {return i+1}
-		};
-		return aBlock._value();
-	'>
-!
-
 indexOf: anObject startingAt: start
 indexOf: anObject startingAt: start
 	"Answer the index of the first occurence of anElement after start
 	"Answer the index of the first occurence of anElement after start
 	within the receiver. If the receiver does not contain anElement,
 	within the receiver. If the receiver does not contain anElement,
@@ -1006,12 +997,7 @@ indexOf: anObject startingAt: start
 !
 !
 
 
 indexOf: anObject startingAt: start ifAbsent: aBlock
 indexOf: anObject startingAt: start ifAbsent: aBlock
-	<inlineJS: '
-		for(var i=start - 1; i < self.length; i++){
-			if($recv(self[i]).__eq(anObject)) {return i+1}
-		}
-		return aBlock._value();
-	'>
+	self subclassResponsibility
 !
 !
 
 
 last
 last
@@ -1031,14 +1017,6 @@ second
 	^ self at: 2
 	^ self at: 2
 !
 !
 
 
-single
-<inlineJS: '
-	if (self.length == 0) throw new Error("Collection is empty");
-	if (self.length > 1) throw new Error("Collection holds more than one element.");
-	return self[0];
-'>
-!
-
 third
 third
 	^ self at: 3
 	^ self at: 3
 ! !
 ! !
@@ -1077,42 +1055,8 @@ copyFrom: anIndex to: anotherIndex
 
 
 !SequenceableCollection methodsFor: 'enumerating'!
 !SequenceableCollection methodsFor: 'enumerating'!
 
 
-detect: aBlock ifNone: anotherBlock
-	<inlineJS: '
-		for(var i = 0; i < self.length; i++)
-			if(aBlock._value_(self[i]))
-				return self[i];
-		return anotherBlock._value();
-	'>
-!
-
-do: aBlock
-	<inlineJS: '
-		for(var i=0; i < self.length; i++) {
-			aBlock._value_(self[i]);
-		}
-	'>
-!
-
 reverseDo: aBlock
 reverseDo: aBlock
 	self reversed do: aBlock
 	self reversed do: aBlock
-!
-
-with: anotherCollection do: aBlock
-	<inlineJS: '
-	    $recv(anotherCollection)._first_(0); // #guardSequenceableCollection
-		for(var i=0; i<self.length; i++) {
-			aBlock._value_value_(self[i], anotherCollection[i]);
-		}
-	'>
-!
-
-withIndexDo: aBlock
-	<inlineJS: '
-		for(var i=0; i < self.length; i++) {
-			aBlock._value_value_(self[i], i+1);
-		}
-	'>
 ! !
 ! !
 
 
 !SequenceableCollection methodsFor: 'streaming'!
 !SequenceableCollection methodsFor: 'streaming'!
@@ -2401,3 +2345,74 @@ fromString: aString flag: anotherString
 	<inlineJS: 'return new RegExp(aString, anotherString)'>
 	<inlineJS: 'return new RegExp(aString, anotherString)'>
 ! !
 ! !
 
 
+Trait named: #TNativeZeroBasedCollection
+	package: 'Kernel-Collections'!
+
+!TNativeZeroBasedCollection methodsFor: 'accessing'!
+
+indexOf: anObject ifAbsent: aBlock
+	<inlineJS: '
+		for(var i=0; i < self.length; i++) {
+			if($recv(self[i]).__eq(anObject)) {return i+1}
+		};
+		return aBlock._value();
+	'>
+!
+
+indexOf: anObject startingAt: start ifAbsent: aBlock
+	<inlineJS: '
+		for(var i=start - 1; i < self.length; i++){
+			if($recv(self[i]).__eq(anObject)) {return i+1}
+		}
+		return aBlock._value();
+	'>
+!
+
+single
+<inlineJS: '
+	if (self.length == 0) throw new Error("Collection is empty");
+	if (self.length > 1) throw new Error("Collection holds more than one element.");
+	return self[0];
+'>
+! !
+
+!TNativeZeroBasedCollection methodsFor: 'enumerating'!
+
+detect: aBlock ifNone: anotherBlock
+	<inlineJS: '
+		for(var i = 0; i < self.length; i++)
+			if(aBlock._value_(self[i]))
+				return self[i];
+		return anotherBlock._value();
+	'>
+!
+
+do: aBlock
+	<inlineJS: '
+		for(var i=0; i < self.length; i++) {
+			aBlock._value_(self[i]);
+		}
+	'>
+!
+
+with: anotherCollection do: aBlock
+	<inlineJS: '
+	    $recv(anotherCollection)._first_(0); // #guardSequenceableCollection
+		for(var i=0; i<self.length; i++) {
+			aBlock._value_value_(self[i], anotherCollection[i]);
+		}
+	'>
+!
+
+withIndexDo: aBlock
+	<inlineJS: '
+		for(var i=0; i < self.length; i++) {
+			aBlock._value_value_(self[i], i+1);
+		}
+	'>
+! !
+
+Array setTraitComposition: {TNativeZeroBasedCollection} asTraitComposition!
+String setTraitComposition: {TNativeZeroBasedCollection} asTraitComposition!
+! !
+