Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
436 lines (395 sloc) 17.5 KB
/* -*- c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package
{
[native(cls="ArrayClass", gc="exact", instance="ArrayObject", methods="auto")]
public dynamic class Array extends Object
{
// option flags for sort and sortOn
public static const CASEINSENSITIVE:uint = 1;
public static const DESCENDING:uint = 2;
public static const UNIQUESORT:uint = 4;
public static const RETURNINDEXEDARRAY:uint = 8;
public static const NUMERIC:uint = 16;
// Functions insertAt() and removeAt() are AS3 extensions not present in ECMAscript.
// They are defined only in the AS3 namespace to avoid breaking ES3 compatibility,
// thus we do not define prototype.insertAt and prototype.removeAt.
[API(CONFIG::SWF_30)]
AS3 native function insertAt(index:int, element:*):void
[API(CONFIG::SWF_30)]
AS3 native function removeAt(index:int):*
// E262 {DontEnum, DontDelete}
public native function get length():uint
public native function set length(newLength:uint)
// Assigns this.length = newLength if latter fits; otherwise
// throws exception or assigns altLength (SWF version dependent).
//
// It is responsibility of caller to provide an appropriate
// altLength. Old behavior used altLength == uint(newLength),
// but it is better to clamp rather than wrap in such cases.
// More discussion on Bugzilla 658677, 661330, and 681399.
private function set_length(newLength:*, altLength:uint)
{
if (newLength is uint)
this.length = newLength;
else if (bugzilla(661330))
Error.throwError( RangeError, 2108, // kInvalidArrayLengthError
newLength );
else
this.length = altLength;
}
// Array.length = 1 per ES3
public static const length:int = 1
// ECMA 15.4.2.2
public function Array(...args)
{
var n:uint = args.length
if (n == 1 && (args[0] is Number))
{
var dlen:Number = args[0];
var ulen:uint = dlen
if (ulen != dlen)
Error.throwError( RangeError, 1005 /*kArrayIndexNotIntegerError*/, dlen );
length = ulen;
}
else
{
// FIXME why not just return args?
length = n
for (var i:uint=0; i < n; i++)
this[i] = args[i]
}
}
/**
15.4.4.5 Array.prototype.join (separator)
The elements of the array are converted to strings, and these strings are then concatenated, separated by
occurrences of the separator. If no separator is provided, a single comma is used as the separator.
The join method takes one argument, separator, and performs the following steps:
1. Call the [[Get]] method of this object with argument "length".
2. Call ToUint32(Result(1)).
3. If separator is undefined, let separator be the single-character string ",".
4. Call ToString(separator).
5. If Result(2) is zero, return the empty string.
6. Call the [[Get]] method of this object with argument "0".
7. If Result(6) is undefined or null, use the empty string; otherwise, call ToString(Result(6)).
8. Let R be Result(7).
9. Let k be 1.
10. If k equals Result(2), return R.
11. Let S be a string value produced by concatenating R and Result(4).
12. Call the [[Get]] method of this object with argument ToString(k).
13. If Result(12) is undefined or null, use the empty string; otherwise, call ToString(Result(12)).
14. Let R be a string value produced by concatenating S and Result(13).
15. Increase k by 1.
16. Go to step 10.
*/
private static function _join(o, sep):String
{
var s:String = (sep === undefined) ? "," : String(sep)
var out:String = ""
for (var i:uint = 0, n:uint=uint(o.length); i < n; i++)
{
var x = o[i]
if (x != null)
out += x
if (i+1 < n)
out += s
}
return out
}
AS3 function join(sep=void 0):String
{
return _join(this, sep)
}
prototype.join = function(sep=void 0):String
{
return _join(this, sep)
}
private static native function _pop(o)
AS3 native function pop()
prototype.pop = function()
{
return _pop(this)
}
/**
15.4.4.2 Array.prototype.toString ( )
The result of calling this function is the same as if the built-in join method were invoked for this object with no
argument.
The toString function is not generic; it throws a TypeError exception if its this value is not an Array object.
Therefore, it cannot be transferred to other kinds of objects for use as a method.
*/
prototype.toString = function():String
{
var a:Array = this // TypeError if not compatible
return _join(a, ",");
}
/**
15.4.4.3 Array.prototype.toLocaleString ( )
The elements of the array are converted to strings using their toLocaleString methods, and these strings are
then concatenated, separated by occurrences of a separator string that has been derived in an implementationdefined
locale-specific way. The result of calling this function is intended to be analogous to the result of
toString, except that the result of this function is intended to be locale-specific.
The result is calculated as follows:
1. Call the [[Get]] method of this object with argument "length".
2. Call ToUint32(Result(1)).
3. Let separator be the list-separator string appropriate for the host environment's current locale (this is derived in
an implementation-defined way).
4. Call ToString(separator).
5. If Result(2) is zero, return the empty string.
6. Call the [[Get]] method of this object with argument "0".
7. If Result(6) is undefined or null, use the empty string; otherwise, call ToObject(Result(6)).toLocaleString().
8. Let R be Result(7).
9. Let k be 1.
10. If k equals Result(2), return R.
11. Let S be a string value produced by concatenating R and Result(4).
12. Call the [[Get]] method of this object with argument ToString(k).
13. If Result(12) is undefined or null, use the empty string; otherwise, call ToObject(Result(12)).toLocaleString().
14. Let R be a string value produced by concatenating S and Result(13).
15. Increase k by 1.
16. Go to step 10.
The toLocaleString function is not generic; it throws a TypeError exception if its this value is not an Array
object. Therefore, it cannot be transferred to other kinds of objects for use as a method.
*/
prototype.toLocaleString = function():String
{
var a:Array = this // TypeError if not compatible
var out:String = ""
for (var i:uint = 0, n:uint=a.length; i < n; i++)
{
var x = a[i]
if (x != null)
out += x.toLocaleString()
if (i+1 < n)
out += ","
}
return out
}
/**
When the push method is called with zero or more arguments item1, item2, etc., the following steps are taken:
1. Call the [[Get]] method of this object with argument "length".
2. Let n be the result of calling ToUint32(Result(1)).
3. Get the next argument in the argument list; if there are no more arguments, go to step 7.
4. Call the [[Put]] method of this object with arguments ToString(n) and Result(3).
5. Increase n by 1.
6. Go to step 3.
7. Call the [[Put]] method of this object with arguments "length" and n.
8. Return n.
The length property of the push method is 1.
NOTE The push function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be
transferred to other kinds of objects for use as a method. Whether the push function can be applied successfully to a host object
is implementation-dependent.
*/
AS3 native function push(...args):uint
prototype.push = function(...args):uint
{
var n:uint = uint(this.length)
for (var i:uint=0, argc:uint=args.length; i < argc; i++)
this[n++] = args[i]
this.length = n
return n
}
private static native function _reverse(o)
AS3 function reverse():Array
{
return _reverse(this) // return will cast to Array
}
prototype.reverse = function()
{
return _reverse(this)
}
private static native function _concat(o, args:Array):Array
AS3 function concat(...args):Array
{
return _concat(this, args)
}
prototype.concat = function(...args):Array
{
return _concat(this, args)
}
private static native function _shift(o)
AS3 function shift()
{
return _shift(this)
}
prototype.shift = function()
{
return _shift(this)
}
private static native function _slice(o, A:Number, B:Number):Array
AS3 function slice(A=0, B=0xffffffff):Array
{
return _slice(this, Number(A), Number(B))
}
prototype.slice = function(A=0, B=0xffffffff):Array
{
return _slice(this, Number(A), Number(B))
}
/**
15.4.4.13 Array.prototype.unshift ( [ item1 [ , item2 [ , ... ] ] ] )
The arguments are prepended to the start of the array, such that their order within the array is the same as the
order in which they appear in the argument list.
When the unshift method is called with zero or more arguments item1, item2, etc., the following steps are taken:
1. Call the [[Get]] method of this object with argument "length".
2. Call ToUint32(Result(1)).
3. Compute the number of arguments.
4. Let k be Result(2).
5. If k is zero, go to step 15.
6. Call ToString(k-1).
7. Call ToString(k+Result(3)-1).
8. If this object has a property named by Result(6), go to step 9; but if this object has no property named by
Result(6), then go to step 12.
9. Call the [[Get]] method of this object with argument Result(6).
10. Call the [[Put]] method of this object with arguments Result(7) and Result(9).
11. Go to step 13.
12. Call the [[Delete]] method of this object with argument Result(7).
13. Decrease k by 1.
14. Go to step 5.
15. Let k be 0.
16. Get the next argument in the part of the argument list that starts with item1; if there are no more arguments, go
to step 21.
17. Call ToString(k).
18. Call the [[Put]] method of this object with arguments Result(17) and Result(16).
19. Increase k by 1.
20. Go to step 16.
21. Call the [[Put]] method of this object with arguments "length" and (Result(2)+Result(3)).
22. Return (Result(2)+Result(3)).
The length property of the unshift method is 1.
NOTE The unshift function is intentionally generic; it does not require that its this value be an Array object. Therefore it can
be transferred to other kinds of objects for use as a method. Whether the unshift function can be applied successfully to a
host object is implementation-dependent.
*/
private static native function _unshift(o, args:Array):uint
native AS3 function unshift(...args):uint
prototype.unshift = function(...args):uint
{
if (this is Array)
return _unshift(this, args);
var len:uint = uint(this.length)
var argc:uint = args.length
var k:uint
for (k=len; k > 0; )
{
k--
var d:uint = k+argc
if (k in this)
this[d] = this[k]
else
delete this[d]
}
for (var i:uint = 0; i < argc; i++)
this[k++] = args[i]
len += argc
this.length = len
return len
}
private static native function _splice(o, args:Array):Array
// splice with zero args returns undefined. All other cases return Array.
AS3 function splice(...args)
{
if (!args.length)
return undefined;
return _splice(this, args)
}
prototype.splice = function(...args)
{
if (!args.length)
return undefined;
return _splice(this, args)
}
// sort can return an Array or a Number (unique sort option)
private static native function _sort(o, args:Array)
AS3 function sort(...args)
{
return _sort (this, args);
}
prototype.sort = function(...args)
{
return _sort (this, args);
}
private static native function _sortOn(o, names, options)
AS3 function sortOn(names, options=0, ...ignored)
{
// this is our own addition so we don't have to make names be optional
return _sortOn(this, names, options);
}
prototype.sortOn = function(names, options=0, ...ignored)
{
return _sortOn(this, names, options)
}
// Array extensions that are in Mozilla...
// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array
//
// These all work on generic objects (array like objects) as well as arrays
private static native function _indexOf (o, searchElement, fromIndex:int):int;
AS3 function indexOf(searchElement, fromIndex=0):int
{
return _indexOf (this, searchElement, int(fromIndex));
}
prototype.indexOf = function(searchElement, fromIndex=0):int
{
return _indexOf (this, searchElement, int(fromIndex));
}
private static native function _lastIndexOf (o, searchElement, fromIndex:int=0):int;
AS3 function lastIndexOf(searchElement, fromIndex=0x7fffffff):int
{
return _lastIndexOf (this, searchElement, int(fromIndex));
}
prototype.lastIndexOf = function(searchElement, fromIndex=0x7fffffff):int
{
return _lastIndexOf (this, searchElement, int(fromIndex));
}
// Returns true if every element in this array satisfies the provided testing function.
private static native function _every(o, callback:Function, thisObject):Boolean;
AS3 function every(callback:Function, thisObject=null):Boolean
{
return _every (this, callback, thisObject);
}
prototype.every = function(callback:Function, thisObject=null):Boolean
{
return _every (this, callback, thisObject);
}
// Creates a new array with all elements that pass the test implemented by the provided function.
private static native function _filter(o, callback:Function, thisObject):Array;
AS3 function filter(callback:Function, thisObject=null):Array
{
return _filter (this, callback, thisObject);
}
prototype.filter = function(callback:Function, thisObject=null):Array
{
return _filter (this, callback, thisObject);
}
// Calls a function for each element in the array.
private static native function _forEach(o, callback:Function, thisObject):void;
AS3 function forEach(callback:Function, thisObject=null):void
{
_forEach (this, callback, thisObject);
}
prototype.forEach = function(callback:Function, thisObject=null):void
{
_forEach (this, callback, thisObject);
}
// Creates a new array with the results of calling a provided function on every element in this array.
private native static function _map(o, callback:Function, thisObject):Array;
AS3 function map(callback:Function, thisObject=null):Array
{
return _map (this, callback, thisObject);
}
prototype.map = function(callback:Function, thisObject=null):Array
{
return _map (this, callback, thisObject);
}
// Returns true if at least one element in this array satisfies the provided testing function.
private static native function _some(o, callback:Function, thisObject):Boolean;
AS3 function some(callback:Function, thisObject=null):Boolean
{
return _some (this, callback, thisObject);
}
prototype.some = function(callback:Function, thisObject=null):Boolean
{
return _some (this, callback, thisObject);
}
_dontEnumPrototype(prototype);
}
}
You can’t perform that action at this time.