Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

overload2

Package Overview
Dependencies
Maintainers
2
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

overload2 - npm Package Compare versions

Comparing version 0.2.1 to 0.3.0

dist/overload2.min.js.map

12

CHANGELOG.md

@@ -5,6 +5,16 @@ # overload2

## [0.2.1] - 2017-09
## [0.3.0] - Feb 23th, 2018, RISKY
### New
* Optional parameter avaiable.
### Fixed
* Bugs hiding in mutable parameters.
## [0.2.1] - Nov, 2017
### Fixed
* In the previous version, if argument is valued with null / undefined and param is not defined with NULL / UNDEFINED, overload2 will conclude that the argument and the param are not matching, even if the param's datatype accepts null / undefined. It is really ambiguous and has been corrected in this version.

@@ -11,0 +21,0 @@

661

dist/overload2.js
/**
* 函数多态的中量级实现。
* @author youngoat@163.com
*
* 注释中的术语表:
* * 参数 = 定义中的形式参数
* * 值组 = 多态函数调用时的实际参数表
*/
/* eslint-disable no-shadow-restricted-names */
(function(global, undefined) {
var MODULE_REQUIRE

@@ -37,4 +41,6 @@ /* built-in */

/* eslint-disable new-cap */
var err = new parent;
this.stack = [ this.name + ': ' + this.message ].concat( err.stack.split('\n').slice(2) ).join('\n');
/* eslint-enable new-cap */
this.stack = [ this.name + ': ' + this.message ].concat(err.stack.split('\n').slice(2)).join('\n');
};

@@ -56,2 +62,3 @@

// 同时,我们在自定义错误的设计上也尽量遵循了准确和具有建设性的原则。
/* eslint-disable key-spacing, comma-style */
, ERR = {

@@ -65,3 +72,3 @@ Generic: declareException('Error'),

Type: declareException('TypeError', TypeError, function(/*string*/ desc, /*string|Array*/ types, /*string*/ actual) {
this.message = desc + ' must be ' + ( typeof types == 'string' ? types : types.join(' | ') ) + ': ' + actual;
this.message = desc + ' must be ' + (typeof types == 'string' ? types : types.join(' | ')) + ': ' + actual;
}),

@@ -79,2 +86,3 @@

}
/* eslint-enable key-spacing, comma-style */

@@ -97,9 +105,34 @@ /**

// 数据是否包含指定元素。
// 数组是否包含指定元素。
, has = function(arr, item) {
return arr.indexOf(item) >= 0;
}
// 数组中的每个元素是否均能通过指定函数的测试。
, eachMatch = function(arr, fn) {
var matched = true;
for (var i = 0; matched && i < arr.length; i++) {
matched = fn(arr[i], i);
}
return matched;
}
// 数组中任意元素通过指定函数的测试。
, onceMatch = function(arr, fn) {
var matched = false;
for (var i = 0; !matched && i < arr.length; i++) {
matched = fn(arr[i], i);
}
return matched;
}
;
/**
* 自定义缺省值类。
*/
function Absent(value) {
this.value = value;
}
/**
* 自定义数据类型类。

@@ -121,36 +154,88 @@ * @param {function} matcher

if (matcher instanceof RegExp)
this.match = function(value) { return matcher.test(value); }
else
if (matcher instanceof RegExp) {
this.match = function(value) {
return matcher.test(value);
};
}
else {
this.match = matcher;
}
}
// ---------------------------
// 预定义数据类型。
Type.ANY = new Type(function() {
return true;
});
Type.BOOLEAN = new Type(function(value) {
return typeof value === 'boolean';
});
Type.CHAR = new Type(function(value) {
return typeof value === 'string' && value.length == 1;
});
Type.NUMBER = new Type(function(value) {
return typeof value === 'number';
});
Type.PLAIN_OBJECT = new Type(function(value) {
return typeof value === 'object' && value.constructor === Object;
});
Type.SCALAR = new Type(function(value) {
return [ 'boolean', 'number', 'string' ].indexOf(typeof value) >= 0;
});
Type.STRING = new Type(function(value) {
return typeof value === 'string';
});
// ---------------------------
// 自定义数据类型生成器。
/**
* 参数类。
* 构造函数支持重载,可能的参数形式包括:
* "alias ...decorator"
* type, ...decorator
* type, decorators
* 其中 type 可以是 Type 对象、普通的构造函数或者类型别名,decorators 则代表由多个修饰符组成的字符串,以空格分隔。
* 创建枚举类型。
*/
function Param() {
if (arguments.length == 0) {
throw new ERR.Arguments('1+', 0);
}
Type.enum = function() {
var args = Array.from(arguments);
return new Type(function(value) {
return args.indexOf(value) >= 0;
});
};
if (arguments.length == 1 && arguments[0] instanceof Param) {
return arguments[0];
}
// ---------------------------
// 有关类型的逻辑工具。
var type = arguments[0], decos = [];
// 根据现有类型,创建新的复合类型。
Type.and = function() {
var types = Array.from(arguments).map(Type.parse);
return new Type(function(value) {
return eachMatch(types, function(type) {
return type.match(value);
});
});
};
// ---------------------------
// 处理数据类型。
// 根据现有类型,创建新的复合类型。
Type.or = function() {
var types = Array.from(arguments).map(Type.parse);
return new Type(function(value) {
return onceMatch(types, function(type) {
return type.match(value);
});
});
};
// 取当前类型的补集。
Type.not = function(type) {
return new Type(function(value) {
return !type.match(value);
});
};
Type.parse = function(type) {
if (typeof type == 'string') {
// 如果首参数是字符串,则它可能包括数据类型别名及修饰符,我们需要首先将其拆分。
// 拆分后第一个字符串作为数据类型(别名,后面还会继续处理),其余作为修饰符。
decos = type.trim().split(/\s+/);
type = decos.shift();
var formalType = TYPE_ALIAS[type];

@@ -180,16 +265,145 @@ if (!formalType) {

}
this.type = type;
return type;
};
/**
* 参数类。
* 构造函数支持重载,可能的参数形式包括:
* "<alias> ...<decorator>"
* type, ...decorator
* type, decorators
* 其中 type 可以是 Type 对象、普通的构造函数或者类型别名,decorators 则代表由多个修饰符组成的字符串,以空格分隔。
*/
function Param() {
if (arguments.length == 0) {
throw new ERR.Arguments('1+', 0);
}
if (arguments.length == 1 && arguments[0] instanceof Param) {
return arguments[0];
}
this.type = null;
this.minSize = 1;
this.maxSize = 1;
this.nil = false;
this.undef = false;
this.absent = false;
this.absentValue = undefined;
this.arrayed = false;
var setSize = (function(size) {
if (typeof size == 'string') {
// 清除所有空白字符。
size = size.replace(/\s/g, '');
if (size == '*' || size == '...') {
this.minSize = 0;
this.maxSize = Infinity;
this.arrayed = true;
return true;
}
if (size == '+') {
this.minSize = 1;
this.maxSize = Infinity;
this.arrayed = true;
return true;
}
// 区间形式。
if (/^\{.+\}$/.test(size)) {
size = size.slice(1, -1);
}
if (/^\d+$/.test(size)) {
this.minSize = this.maxSize = parseInt(size);
this.arrayed = true;
return true;
}
if (/^,(\d+)$/.test(size)) {
this.minSize = 0;
this.maxSize = parseInt(RegExp.$1);
this.arrayed = true;
return true;
}
if (/^(\d+),$/.test(size)) {
this.minSize = parseInt(RegExp.$1);
this.maxSize = Infinity;
this.arrayed = true;
return true;
}
if (/^(\d+),(\d+)$/.test(size)) {
this.minSize = parseInt(RegExp.$1);
this.maxSize = parseInt(RegExp.$2);
this.arrayed = true;
return true;
}
return false;
}
if (Number.isInteger(size) && size > 0) {
this.minSize = this.maxSize = size;
this.arrayed = true;
return true;
}
return false;
}).bind(this);
var type = arguments[0], decos = [];
// ---------------------------
// 处理特殊的参数占位符。
if (setSize(type)) {
this.type = Type.ANY;
return this;
}
// ---------------------------
// 处理数据类型。
if (typeof type == 'string') {
// 如果首参数是字符串,则它可能包括数据类型别名及修饰符,我们需要首先将其拆分。
// 拆分后第一个字符串作为数据类型(别名,后面还会继续处理),其余作为修饰符。
decos = type.trim().split(/\s+/);
type = decos.shift();
}
this.type = Type.parse(type);
// ---------------------------
// 处理修饰符。
var DECOS = ['NULL', 'UNDEFINED'];
var DECOS = ['NULL', 'UNDEFINED', 'ABSENT'], i;
for (var i = 1; i < arguments.length; i++) {
decos = decos.concat(arguments[i].trim().split(/\s+/));
for (i = 1; i < arguments.length; i++) {
if (typeof arguments[i] == 'string') {
decos = decos.concat(arguments[i].trim().split(/\s+/));
}
else if (Number.isInteger(arguments[i])) {
decos.push(arguments[i]);
}
// @tag 20180222
else if (arguments[i] instanceof Absent) {
this.absent = true;
this.absentValue = arguments[i].value;
}
}
for (var i = 0; i < decos.length; i++) {
for (i = 0; i < decos.length; i++) {
var rawDeco = decos[i];
// 修饰符不区分大小写。
// 尝试作为量化修饰符应用。
if (setSize(rawDeco)) continue;
// 设置缺省值。
// 注意:为避免歧义,缺省值字面量中不得出现空格。
// @tag 20180222
if (/^=(.+)$/.test(rawDeco)) {
this.absent = true;
this.absentValue = eval(RegExp.$1);
continue;
}
// 普通修饰符不区分大小写。
decos[i] = decos[i].toUpperCase();

@@ -206,6 +420,11 @@

// 参数是否可以为 null
this.nil = has(decos, 'null');
this.nil = has(decos, 'NULL');
// 参数是否可以为 undefined
this.undef = has(decos, 'undefined');
this.undef = has(decos, 'UNDEFINED');
// 参数是否可以缺席。
if (!this.absent) {
this.absent = has(decos, 'ABSENT');
}
}

@@ -215,6 +434,11 @@

// 判断值是否合乎参数限定。
/**
* 判断值是否合乎参数限定。
*/
Param.prototype.satisfy = function(value) {
if (value === null && this.nil) return true;
if (value === undefined && this.undef) return true;
// if (value === null && this.nil) return true;
// if (value === undefined && this.undef) return true;
if (value === null) return this.nil;
if (value === undefined) return this.undef;
return this.type.match(value);

@@ -229,11 +453,23 @@ };

var params = [];
var minSize = 0;
var maxSize = 0;
var easy = true;
for (var i = 0, args; i < arguments.length; i++) {
args = (arguments[i] instanceof Array) ? arguments[i] : [ arguments[i] ];
params[i] = Param.parse.apply(null, args);
maxSize += params[i].maxSize;
// @tag 20180222
// 如果参数允许缺省,则在整个实参列表中占据的最小长度为 0。
minSize += params[i].absent ? 0 : params[i].minSize;
// 如果形参可缺省,或者为多占位或可变长度,则不适用简易模式。
easy = easy && !( params[i].absent || params[i].arrayed );
}
this.length = params.length;
this.item = function(i) {
return params[i];
};
this.easy = easy;
this.minSize = minSize;
this.maxSize = maxSize;
this.params = params;
}

@@ -244,16 +480,188 @@

/**
* 判断值组是否合乎参数值限定。
* 判断值组是否合乎参数定义。
* @deprecated 为了支持可变长度参数,用更复杂的 .parse() 方法取代。
*/
ParamList.prototype.satisfy = function(args) {
// 参数表长度检查。
if (args.length != this.length) {
if (args.length != this.params.length) {
return false;
}
// 参数类型核对
var matched = true;
for (var i = 0; matched && i < this.length; i++) {
matched = this.item(i).satisfy(args[i]);
// 参数类型核对。
return eachMatch(this.params, function(param, index) {
return param.satisfy(args[index]);
});
}
/**
* 尝试按参数定义解析值组。
* @return false 匹配失败
* @return Array 匹配成功,返回与定义一一对应的新值组(因为参数可能是可变长度的)
*/
ParamList.prototype.parse = function(args) {
// ---------------------------
// 检查值组的长度是否在参数列表定义的区间内。
if (args.length < this.minSize || this.maxSize < args.length) {
return null;
}
return matched;
// ---------------------------
// 适用简易匹配逻辑。
if (this.easy) {
var matched = eachMatch(this.params, function(param, index) {
return param.satisfy(args[index]);
});
return matched ? args : null;
}
// ---------------------------
// 否则,适用复杂匹配逻辑。
// 注意:此函数将被递归调用。
var matching = function(args, params) {
var newArgs = [];
var argCursor = 0, paramCursor = 0;
for (; argCursor < args.length; argCursor++) {
// 如果所有形式参数匹配成功之后,仍有多余的实参未参加匹配,则认为整个参数表匹配失败。
if (paramCursor >= params.length) {
return null;
}
// 当前参数。
var param = params[paramCursor];
// 当前实参。
var arg = args[argCursor];
// ---------------------------
// 如果形式参数对应单个实参且不可缺省,则按简易逻辑处理。
if (!param.absent && param.minSize == 1 && param.maxSize == 1) {
if (!param.satisfy(arg)) {
// 如果实参与形式参数不匹配,则终止后续匹配,整个参数表匹配失败。
return null;
}
else {
newArgs.push(arg);
paramCursor++;
}
continue;
}
// ---------------------------
// 否则,适用复杂逻辑。
// 如果剩余实参数量不足以匹配当前形式参数:
if (args.length - argCursor < param.minSize) {
// 若参数可缺省:
if (param.absent) {
// 使用缺省值替补。
newArgs.push(param.absentValue);
// 不消耗实参。
argCursor--;
// 当前形参匹配完毕。
continue;
}
// 否则当前形式参数匹配失败,整个参数表匹配失败。
return null;
}
// 依次储存当前形式参数匹配的实参。
var paramArgs = [];
var pushParamArg = function() {
if (param.arrayed) newArgs.push(paramArgs);
else newArgs.push(paramArgs[0]);
};
for (; argCursor < args.length && param.satisfy(args[argCursor]); argCursor++) {
paramArgs.push(args[argCursor]);
}
argCursor--;
paramCursor++;
// 如当前形式参数匹配实参个数未达到最小值:
if (paramArgs.length < param.minSize) {
// 若参数可缺省:
if (param.absent) {
// 使用缺省值替补。
newArgs.push(param.absentValue);
// 回吐所有已消耗的实参。
argCursor -= paramArgs.length;
// 当前形参匹配完毕。
continue;
}
// 否则当前形式参数匹配失败,整个参数表匹配失败。
return null;
}
var restParams = params.slice(paramCursor);
// 抵达匹配边界时,若
// 仅匹配了最小数量的实参且该参数不可缺省,或者已是最后一个形式参数,
// 则直接固定参数值。
if (!param.absent && paramArgs.length == param.minSize || restParams.length == 0) {
pushParamArg();
continue;
}
// 否则,须尝试让贤。
var restArgs = args.slice(argCursor + 1);
// 步步让贤,直到让无可让。
do {
var restNewArgs = matching(restArgs, restParams);
// 剩余参数匹配成功,则拼接匹配结果,整个参数表匹配成功。
if (restNewArgs != null) {
pushParamArg();
newArgs = newArgs.concat(restNewArgs);
break;
}
// 如果已让无可让:
if (paramArgs.length == param.minSize) {
// 如果参数可以缺省,统统不要了,全给后续形参去。
if (param.absent) {
restArgs = paramArgs.concat(restArgs);
paramArgs = param.absentValue;
continue;
}
// 否则,就此罢了(liao)。
newArgs = null;
break;
}
else {
restArgs.unshift(paramArgs.pop());
}
} while (true);
// 行进至此,不成功,则成仁。
return newArgs;
}
// 此时,所有实参均已消耗完毕。
for (; newArgs.length < params.length; paramCursor++) {
if (params[paramCursor].absent) {
newArgs.push(params[paramCursor].absentValue);
}
else if (params[paramCursor].minSize == 0) {
newArgs.push([]);
}
else {
return null;
}
}
return newArgs;
};
return matching(Array.from(args), this.params);
};

@@ -282,7 +690,9 @@

if (typeof args[0] == 'number') {
if (args.length > 1) {
throw new ERR.Arguments(2, args.length + 1);
}
this.paramCount = args[0];
// 支持可变长度参数后,用于代表值组长度的数字,也可以用 Param 实例来表征。
// 在此我们仍保留 argLength,是出于提高性能的考虑。
if (typeof args[0] == 'number' && args.length == 1) {
// if (args.length > 1) {
// throw new ERR.Arguments(2, args.length + 1);
// }
this.argLength = args[0];
}

@@ -307,9 +717,15 @@ else if (args[0] instanceof ParamList) {

Overload.prototype.exec = function(scope, args) {
// 若指定了形参数量,而实参数量不符,则直接跳过。
if (typeof this.paramCount == 'number' && (args.length != this.paramCount)) {
return false;
// 对于每一个重载实现,值组长度和形参表是互斥的。
// 或者指定值组长度,或者指定形参表,而不是同时指定。
// 如指定值组长度,则仅判断长度。
if (typeof this.argLength == 'number') {
if (args.length != this.argLength) return false;
}
if (this.params && !this.params.satisfy(args)) {
return false;
// 否则,须尝试匹配值组与参数列表。
else {
// 尝试获取按形式参数列表重整后的值组。
args = this.params.parse(args);
if (!args) return false;
}

@@ -360,7 +776,13 @@

if (this._defaultMethod) {
return this.defaultMethod.apply(scope, args);
return this._defaultMethod.apply(scope, args);
}
// 表示没有任何重载形参与实参匹配。
throw new ERR.Unmatching('Unmatching arguments: ' + args);
var types = [];
for (var i = 0, type; i < args.length; i++) {
type = (args[i] === null) ? 'null' : typeof args[i];
if (type === 'object') type = args[i].constructor.name;
types.push(type);
}
throw new ERR.Unmatching('Unmatching arguments: ' + types.join(', '));
};

@@ -392,3 +814,2 @@

if (arguments.length > 2) {
console.warn('redundant arguments found');
}

@@ -408,3 +829,2 @@ }

if (arguments.length > 1) {
console.warn('redundant arguments found');
}

@@ -418,3 +838,2 @@ this._defaultMethod = method;

function Overloader() {
var overloaded = new OverloadedFunction();

@@ -425,19 +844,2 @@ var append = function(args) {

// 保存多态实现。
// 注意:如果多态实现不合规,应当在定义时抛出异常,调用时不再进行合规校验。
var saveDEF = function(args, isDefault) {
var overloadInstance;
if (args[0] instanceof Overload) {
overloadInstance = args[0];
}
else {
overloadInstance = Overload.parse.apply(null, args);
}
overloaded.overload(overloadInstance);
if (isDefault) {
overloaded.defaultMethod = overloadInstance.method;
}
};
if (arguments.length) {

@@ -469,65 +871,40 @@ // append(arguments);

// 预定义数据类型。
// 为了向前兼容,保留 0.1.0 版本之前的预定义数据类型,但以后新增类型仅挂靠 Type 函数。
Overloader.ANY = new Type(function(value) {
return true;
});
Overloader.ANY = Type.ANY;
Overloader.BOOLEAN = Type.BOOLEAN;
Overloader.CHAR = Type.CHAR;
Overloader.NUMBER = Type.NUMBER;
Overloader.SCALAR = Type.SCALAR;
Overloader.STRING = Type.STRING;
Overloader.BOOLEAN = new Type(function(value) {
return typeof value == 'boolean';
});
Overloader.CHAR = new Type(function(value) {
return typeof value == 'string' && value.length == 1;
});
Overloader.NUMBER = new Type(function(value) {
return typeof value == 'number';
});
Overloader.SCALAR = new Type(function(value) {
return [ 'boolean', 'number', 'string' ].indexOf(typeof value) >= 0;
});
Overloader.STRING = new Type(function(value) {
return typeof value == 'string';
});
// ---------------------------
// 自定义数据类型生成器。
// 为了向前兼容,保留 0.1.0 版本之前的数据类型生成工具,但以后新增工具仅挂靠 Type 函数。
/**
* 创建枚举类型。
*/
Overloader.enum = function() {
var args = [];
for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
Overloader.enum = Type.enum;
return new Type(function(value) {
return args.indexOf(value) >= 0;
});
};
// ---------------------------
Overloader.Type = Type;
Overloader.type = Type;
Overloader.parseType = Type;
Overloader.Type = Type;
Overloader.type = Type;
// Overloader.parseType = Type;
Overloader.Param = Param;
Overloader.param = Param.parse;
Overloader.parseParam = Param.parse;
Overloader.Param = Param;
Overloader.param = Param.parse;
Overloader.parseParam = Param.parse;
Overloader.ParamList = ParamList;
Overloader.paramList = ParamList.parse;
Overloader.ParamList = ParamList;
Overloader.paramList = ParamList.parse;
Overloader.parseParamList = ParamList.parse;
Overloader.Overload = Overload;
Overloader.overload = Overload.parse;
Overloader.parseOverload = Overload.parse;
Overloader.Overload = Overload;
Overloader.overload = Overload.parse;
Overloader.parseOverload = Overload.parse;
Overloader.Function = OverloadedFunction;
Overloader.Function = OverloadedFunction;
Overloader.createFunction = OverloadedFunction;
Overloader.absent = function(value) { return new Absent(value); };
// 输出所有自定义异常。

@@ -542,13 +919,13 @@ for (var name in ERR) {

var TYPE_ALIAS = {
'*' : Overloader.ANY
, 'any' : Overloader.ANY
, 'boolean' : Overloader.BOOLEAN
, 'char' : Overloader.CHAR
, 'number' : Overloader.NUMBER
, 'scalar' : Overloader.SCALAR
, 'string' : Overloader.STRING
};
var TYPE_ALIAS =
{ '?' : Type.ANY
, 'any' : Type.ANY
, 'boolean' : Type.BOOLEAN
, 'char' : Type.CHAR
, 'number' : Type.NUMBER
, 'object' : Type.PLAIN_OBJECT
, 'scalar' : Type.SCALAR
, 'string' : Type.STRING
};
// ---------------------------

@@ -563,4 +940,4 @@ // 模块输出

// RequireJS
else if (typeof define == 'function') {
define(function() {
else if (typeof global.define == 'function') {
global.define(function() {
return Overloader;

@@ -567,0 +944,0 @@ });

@@ -1,2 +0,1 @@

(function(t,e){var n,r=function y(t,e,n){if(!e)e=Error;var r=function(r){this.name="OVERLOAD2."+t;if(n){n.apply(this,arguments)}else{this.message=r}var a=new e;this.stack=[this.name+": "+this.message].concat(a.stack.split("\n").slice(2)).join("\n")};r.prototype=Object.create(e.prototype);r.prototype.consturctor=r;r.prototype.toString=r.prototype.valueOf=function(){return"["+this.name+": "+this.message+"]"};Object.defineProperty(r,"name",{value:t});return r},a={Generic:r("Error"),Arguments:r("ArgumentsError",TypeError,function(t,e){this.message=t+" argument(s) expected but actual "+e}),Type:r("TypeError",TypeError,function(t,e,n){this.message=t+" must be "+(typeof e=="string"?e:e.join(" | "))+": "+n}),Range:r("RangeError",RangeError,function(t,e,n){if(e instanceof Array){e=e.join(" | ")}this.message=t+" must be "+e+": "+n}),NotImplemented:r("EmptyException"),Unmatching:r("UnmatchingException",TypeError)},o=function(t){function e(e){return t.apply(this,e)}e.prototype=t.prototype;return function(){return new e(arguments)}},i=function(t,e){return t.indexOf(e)>=0};function s(t){if(arguments.length!=1){throw new a.Arguments(1,arguments.length)}if(!(typeof t=="function"||t instanceof RegExp)){throw new a.Type("Type matcher",["Function","RegExp"],t)}if(!(this instanceof s))return new s(t);if(t instanceof RegExp)this.match=function(e){return t.test(e)};else this.match=t}function u(){if(arguments.length==0){throw new a.Arguments("1+",0)}if(arguments.length==1&&arguments[0]instanceof u){return arguments[0]}var t=arguments[0],e=[];if(typeof t=="string"){e=t.trim().split(/\s+/);t=e.shift();var n=g[t];if(!n){throw new a.Range("type alias",Object.keys(g),t)}t=n}else if(t instanceof s){}else if(typeof t=="function"){t=function(t){return new s(function(e){return e instanceof t})}(t)}else{throw new a.Type("Param type",["overload2.Type","string","Function"],t)}this.type=t;var r=["NULL","UNDEFINED"];for(var o=1;o<arguments.length;o++){e=e.concat(arguments[o].trim().split(/\s+/))}for(var o=0;o<e.length;o++){var f=e[o];e[o]=e[o].toUpperCase();if(!i(r,e[o])){throw new a.Range("param decorator",r,f)}}this.nil=i(e,"null");this.undef=i(e,"undefined")}u.parse=o(u);u.prototype.satisfy=function(t){if(t===null&&this.nil)return true;if(t===e&&this.undef)return true;return this.type.match(t)};function f(){var t=[];for(var e=0,n;e<arguments.length;e++){n=arguments[e]instanceof Array?arguments[e]:[arguments[e]];t[e]=u.parse.apply(null,n)}this.length=t.length;this.item=function(e){return t[e]}}f.parse=o(f);f.prototype.satisfy=function(t){if(t.length!=this.length){return false}var e=true;for(var n=0;e&&n<this.length;n++){e=this.item(n).satisfy(t[n])}return e};function p(){if(arguments.length==0){throw new a.Arguments("1+",0)}var t=Array.from(arguments);var e=t.pop();if(typeof e=="function"){this.method=e}else{throw new a.Generic("overloading implementation function missed")}if(typeof t[0]=="number"){if(t.length>1){throw new a.Arguments(2,t.length+1)}this.paramCount=t[0]}else if(t[0]instanceof f){if(t.length>1){throw new a.Arguments(2,t.length+1)}this.params=t[0]}else{this.params=f.parse.apply(null,t)}}p.parse=o(p);p.prototype.exec=function(t,e){if(typeof this.paramCount=="number"&&e.length!=this.paramCount){return false}if(this.params&&!this.params.satisfy(e)){return false}return[this.method.apply(t,e)]};function l(){if(!(this instanceof l))return new l;this._defaultMethod=null;this._overloads=[]}l.prototype.exec=function(){return this.apply(this,arguments)};l.prototype.apply=function(t,e){if(this._overloads.length==0){throw new a.NotImplemented}for(var n=0,r;n<this._overloads.length;n++){r=this._overloads[n].exec(t,e);if(r){return r[0]}}if(this._defaultMethod){return this.defaultMethod.apply(t,e)}throw new a.Unmatching("Unmatching arguments: "+e)};l.prototype.call=function(t){var e=Array.from(arguments);return this.apply(t,e.slice(1))};l.prototype.overload=function(){var t;if(arguments[0]instanceof p){t=arguments[0];if(arguments[1]){this._defaultMethod=t.method}if(arguments.length>2){console.warn("redundant arguments found")}}else{t=p.parse.apply(null,arguments)}this._overloads.push(t);return this};l.prototype.default=function(t){if(typeof t!="function"){throw new a.Generic("invalid default method")}if(arguments.length>1){console.warn("redundant arguments found")}this._defaultMethod=t};function h(){var t=new l;var e=function(e){t.overload.apply(t,e)};var n=function(e,n){var r;if(e[0]instanceof p){r=e[0]}else{r=p.parse.apply(null,e)}t.overload(r);if(n){t.defaultMethod=r.method}};if(arguments.length){}var r=function(){return t.apply(this,arguments)};r.overload=function(){e(arguments);return r};r.default=function(e){t.default(e);return r};return r}h.ANY=new s(function(t){return true});h.BOOLEAN=new s(function(t){return typeof t=="boolean"});h.CHAR=new s(function(t){return typeof t=="string"&&t.length==1});h.NUMBER=new s(function(t){return typeof t=="number"});h.SCALAR=new s(function(t){return["boolean","number","string"].indexOf(typeof t)>=0});h.STRING=new s(function(t){return typeof t=="string"});h.enum=function(){var t=[];for(var e=0;e<arguments.length;e++){t.push(arguments[e])}return new s(function(e){return t.indexOf(e)>=0})};h.Type=s;h.type=s;h.parseType=s;h.Param=u;h.param=u.parse;h.parseParam=u.parse;h.ParamList=f;h.paramList=f.parse;h.parseParamList=f.parse;h.Overload=p;h.overload=p.parse;h.parseOverload=p.parse;h.Function=l;h.createFunction=l;for(var c in a){if(a.hasOwnProperty(c)){var m=a[c];h[m.name]=m}}var g={"*":h.ANY,any:h.ANY,"boolean":h.BOOLEAN,"char":h.CHAR,number:h.NUMBER,scalar:h.SCALAR,string:h.STRING};if(typeof module=="object"&&typeof module.exports=="object"){module.exports=h}else if(typeof define=="function"){define(function(){return h})}else{t.overload2=h}})(this);
//# sourceMappingURL=overload2.map
(function(global,undefined){var MODULE_REQUIRE,declareException=function e(t,r,n){if(!r)r=Error;var a=function(e){this.name="OVERLOAD2."+t;if(n){n.apply(this,arguments)}else{this.message=e}var a=new r;this.stack=[this.name+": "+this.message].concat(a.stack.split("\n").slice(2)).join("\n")};a.prototype=Object.create(r.prototype);a.prototype.consturctor=a;a.prototype.toString=a.prototype.valueOf=function(){return"["+this.name+": "+this.message+"]"};Object.defineProperty(a,"name",{value:t});return a},ERR={Generic:declareException("Error"),Arguments:declareException("ArgumentsError",TypeError,function(e,t){this.message=e+" argument(s) expected but actual "+t}),Type:declareException("TypeError",TypeError,function(e,t,r){this.message=e+" must be "+(typeof t=="string"?t:t.join(" | "))+": "+r}),Range:declareException("RangeError",RangeError,function(e,t,r){if(t instanceof Array){t=t.join(" | ")}this.message=e+" must be "+t+": "+r}),NotImplemented:declareException("EmptyException"),Unmatching:declareException("UnmatchingException",TypeError)},generateCreator=function(e){function t(t){return e.apply(this,t)}t.prototype=e.prototype;return function(){return new t(arguments)}},has=function(e,t){return e.indexOf(t)>=0},eachMatch=function(e,t){var r=true;for(var n=0;r&&n<e.length;n++){r=t(e[n],n)}return r},onceMatch=function(e,t){var r=false;for(var n=0;!r&&n<e.length;n++){r=t(e[n],n)}return r};function Absent(e){this.value=e}function Type(e){if(arguments.length!=1){throw new ERR.Arguments(1,arguments.length)}if(!(typeof e=="function"||e instanceof RegExp)){throw new ERR.Type("Type matcher",["Function","RegExp"],e)}if(!(this instanceof Type))return new Type(e);if(e instanceof RegExp){this.match=function(t){return e.test(t)}}else{this.match=e}}Type.ANY=new Type(function(){return true});Type.BOOLEAN=new Type(function(e){return typeof e==="boolean"});Type.CHAR=new Type(function(e){return typeof e==="string"&&e.length==1});Type.NUMBER=new Type(function(e){return typeof e==="number"});Type.PLAIN_OBJECT=new Type(function(e){return typeof e==="object"&&e.constructor===Object});Type.SCALAR=new Type(function(e){return["boolean","number","string"].indexOf(typeof e)>=0});Type.STRING=new Type(function(e){return typeof e==="string"});Type.enum=function(){var e=Array.from(arguments);return new Type(function(t){return e.indexOf(t)>=0})};Type.and=function(){var e=Array.from(arguments).map(Type.parse);return new Type(function(t){return eachMatch(e,function(e){return e.match(t)})})};Type.or=function(){var e=Array.from(arguments).map(Type.parse);return new Type(function(t){return onceMatch(e,function(e){return e.match(t)})})};Type.not=function(e){return new Type(function(t){return!e.match(t)})};Type.parse=function(e){if(typeof e=="string"){var t=TYPE_ALIAS[e];if(!t){throw new ERR.Range("type alias",Object.keys(TYPE_ALIAS),e)}e=t}else if(e instanceof Type){}else if(typeof e=="function"){e=function(e){return new Type(function(t){return t instanceof e})}(e)}else{throw new ERR.Type("Param type",["overload2.Type","string","Function"],e)}return e};function Param(){if(arguments.length==0){throw new ERR.Arguments("1+",0)}if(arguments.length==1&&arguments[0]instanceof Param){return arguments[0]}this.type=null;this.minSize=1;this.maxSize=1;this.nil=false;this.undef=false;this.absent=false;this.absentValue=undefined;this.arrayed=false;var setSize=function(e){if(typeof e=="string"){e=e.replace(/\s/g,"");if(e=="*"||e=="..."){this.minSize=0;this.maxSize=Infinity;this.arrayed=true;return true}if(e=="+"){this.minSize=1;this.maxSize=Infinity;this.arrayed=true;return true}if(/^\{.+\}$/.test(e)){e=e.slice(1,-1)}if(/^\d+$/.test(e)){this.minSize=this.maxSize=parseInt(e);this.arrayed=true;return true}if(/^,(\d+)$/.test(e)){this.minSize=0;this.maxSize=parseInt(RegExp.$1);this.arrayed=true;return true}if(/^(\d+),$/.test(e)){this.minSize=parseInt(RegExp.$1);this.maxSize=Infinity;this.arrayed=true;return true}if(/^(\d+),(\d+)$/.test(e)){this.minSize=parseInt(RegExp.$1);this.maxSize=parseInt(RegExp.$2);this.arrayed=true;return true}return false}if(Number.isInteger(e)&&e>0){this.minSize=this.maxSize=e;this.arrayed=true;return true}return false}.bind(this);var type=arguments[0],decos=[];if(setSize(type)){this.type=Type.ANY;return this}if(typeof type=="string"){decos=type.trim().split(/\s+/);type=decos.shift()}this.type=Type.parse(type);var DECOS=["NULL","UNDEFINED","ABSENT"],i;for(i=1;i<arguments.length;i++){if(typeof arguments[i]=="string"){decos=decos.concat(arguments[i].trim().split(/\s+/))}else if(Number.isInteger(arguments[i])){decos.push(arguments[i])}else if(arguments[i]instanceof Absent){this.absent=true;this.absentValue=arguments[i].value}}for(i=0;i<decos.length;i++){var rawDeco=decos[i];if(setSize(rawDeco))continue;if(/^=(.+)$/.test(rawDeco)){this.absent=true;this.absentValue=eval(RegExp.$1);continue}decos[i]=decos[i].toUpperCase();if(!has(DECOS,decos[i])){throw new ERR.Range("param decorator",DECOS,rawDeco)}}this.nil=has(decos,"NULL");this.undef=has(decos,"UNDEFINED");if(!this.absent){this.absent=has(decos,"ABSENT")}}Param.parse=generateCreator(Param);Param.prototype.satisfy=function(e){if(e===null)return this.nil;if(e===undefined)return this.undef;return this.type.match(e)};function ParamList(){var e=[];var t=0;var r=0;var n=true;for(var a=0,i;a<arguments.length;a++){i=arguments[a]instanceof Array?arguments[a]:[arguments[a]];e[a]=Param.parse.apply(null,i);r+=e[a].maxSize;t+=e[a].absent?0:e[a].minSize;n=n&&!(e[a].absent||e[a].arrayed)}this.easy=n;this.minSize=t;this.maxSize=r;this.params=e}ParamList.parse=generateCreator(ParamList);ParamList.prototype.satisfy=function(e){if(e.length!=this.params.length){return false}return eachMatch(this.params,function(t,r){return t.satisfy(e[r])})};ParamList.prototype.parse=function(e){if(e.length<this.minSize||this.maxSize<e.length){return null}if(this.easy){var t=eachMatch(this.params,function(t,r){return t.satisfy(e[r])});return t?e:null}var r=function(e,t){var n=[];var a=0,i=0;for(;a<e.length;a++){if(i>=t.length){return null}var o=t[i];var s=e[a];if(!o.absent&&o.minSize==1&&o.maxSize==1){if(!o.satisfy(s)){return null}else{n.push(s);i++}continue}if(e.length-a<o.minSize){if(o.absent){n.push(o.absentValue);a--;continue}return null}var u=[];var l=function(){if(o.arrayed)n.push(u);else n.push(u[0])};for(;a<e.length&&o.satisfy(e[a]);a++){u.push(e[a])}a--;i++;if(u.length<o.minSize){if(o.absent){n.push(o.absentValue);a-=u.length;continue}return null}var p=t.slice(i);if(!o.absent&&u.length==o.minSize||p.length==0){l();continue}var f=e.slice(a+1);do{var c=r(f,p);if(c!=null){l();n=n.concat(c);break}if(u.length==o.minSize){if(o.absent){f=u.concat(f);u=o.absentValue;continue}n=null;break}else{f.unshift(u.pop())}}while(true);return n}for(;n.length<t.length;i++){if(t[i].absent){n.push(t[i].absentValue)}else if(t[i].minSize==0){n.push([])}else{return null}}return n};return r(Array.from(e),this.params)};function Overload(){if(arguments.length==0){throw new ERR.Arguments("1+",0)}var e=Array.from(arguments);var t=e.pop();if(typeof t=="function"){this.method=t}else{throw new ERR.Generic("overloading implementation function missed")}if(typeof e[0]=="number"&&e.length==1){this.argLength=e[0]}else if(e[0]instanceof ParamList){if(e.length>1){throw new ERR.Arguments(2,e.length+1)}this.params=e[0]}else{this.params=ParamList.parse.apply(null,e)}}Overload.parse=generateCreator(Overload);Overload.prototype.exec=function(e,t){if(typeof this.argLength=="number"){if(t.length!=this.argLength)return false}else{t=this.params.parse(t);if(!t)return false}return[this.method.apply(e,t)]};function OverloadedFunction(){if(!(this instanceof OverloadedFunction))return new OverloadedFunction;this._defaultMethod=null;this._overloads=[]}OverloadedFunction.prototype.exec=function(){return this.apply(this,arguments)};OverloadedFunction.prototype.apply=function(e,t){if(this._overloads.length==0){throw new ERR.NotImplemented}for(var r=0,n;r<this._overloads.length;r++){n=this._overloads[r].exec(e,t);if(n){return n[0]}}if(this._defaultMethod){return this._defaultMethod.apply(e,t)}var a=[];for(var r=0,i;r<t.length;r++){i=t[r]===null?"null":typeof t[r];if(i==="object")i=t[r].constructor.name;a.push(i)}throw new ERR.Unmatching("Unmatching arguments: "+a.join(", "))};OverloadedFunction.prototype.call=function(e){var t=Array.from(arguments);return this.apply(e,t.slice(1))};OverloadedFunction.prototype.overload=function(){var e;if(arguments[0]instanceof Overload){e=arguments[0];if(arguments[1]){this._defaultMethod=e.method}if(arguments.length>2){}}else{e=Overload.parse.apply(null,arguments)}this._overloads.push(e);return this};OverloadedFunction.prototype.default=function(e){if(typeof e!="function"){throw new ERR.Generic("invalid default method")}if(arguments.length>1){}this._defaultMethod=e};function Overloader(){var e=new OverloadedFunction;var t=function(t){e.overload.apply(e,t)};if(arguments.length){}var r=function(){return e.apply(this,arguments)};r.overload=function(){t(arguments);return r};r.default=function(t){e.default(t);return r};return r}Overloader.ANY=Type.ANY;Overloader.BOOLEAN=Type.BOOLEAN;Overloader.CHAR=Type.CHAR;Overloader.NUMBER=Type.NUMBER;Overloader.SCALAR=Type.SCALAR;Overloader.STRING=Type.STRING;Overloader.enum=Type.enum;Overloader.Type=Type;Overloader.type=Type;Overloader.Param=Param;Overloader.param=Param.parse;Overloader.parseParam=Param.parse;Overloader.ParamList=ParamList;Overloader.paramList=ParamList.parse;Overloader.parseParamList=ParamList.parse;Overloader.Overload=Overload;Overloader.overload=Overload.parse;Overloader.parseOverload=Overload.parse;Overloader.Function=OverloadedFunction;Overloader.createFunction=OverloadedFunction;Overloader.absent=function(e){return new Absent(e)};for(var name in ERR){if(ERR.hasOwnProperty(name)){var Err=ERR[name];Overloader[Err.name]=Err}}var TYPE_ALIAS={"?":Type.ANY,any:Type.ANY,boolean:Type.BOOLEAN,char:Type.CHAR,number:Type.NUMBER,object:Type.PLAIN_OBJECT,scalar:Type.SCALAR,string:Type.STRING};if(typeof module=="object"&&typeof module.exports=="object"){module.exports=Overloader}else if(typeof global.define=="function"){global.define(function(){return Overloader})}else{global.overload2=Overloader}})(this);

@@ -12,5 +12,8 @@ /**

// Decorators are appended to the param after datatype.
[ Date, 'null', 'undefined' ],
// Decorator "null" means actual value `null` is accepted.
// Decorator "undefined" means actual value `undefined` is accepted.
// ATTENTION: Decorators are case insensitive.
[ Date, 'null', 'unDefined' ],
function date_instance(d) {
function f_date(d) {
if (d === null || d === undefined) {

@@ -22,6 +25,6 @@ d = new Date(0);

)
.default(
function date_others() {
var d = new Date();
return 1900 + d.getYear();
function f_now() {
return 1900 + (new Date).getYear();
}

@@ -31,10 +34,12 @@ )

// date_instance invoked.
// f_date() invoked.
var year = getYear(null);
assert.equal(1970, year);
// date_instance invoked.
// f_date() invoked.
var year = getYear(undefined);
assert.equal(1970, year);
var year = getYear();
console.log('THIS LINE REACHED MEANS EVERYTHING IS OK.');

@@ -126,2 +126,9 @@ /**

/**
* 自定义缺省值类。
*/
function Absent(value) {
this.value = value;
}
/**
* 自定义数据类型类。

@@ -260,3 +267,3 @@ * @param {function} matcher

* 构造函数支持重载,可能的参数形式包括:
* "alias ...decorator"
* "<alias> ...<decorator>"
* type, ...decorator

@@ -280,2 +287,5 @@ * type, decorators

this.undef = false;
this.absent = false;
this.absentValue = undefined;
this.arrayed = false;

@@ -289,2 +299,3 @@ var setSize = (function(size) {

this.maxSize = Infinity;
this.arrayed = true;
return true;

@@ -295,2 +306,3 @@ }

this.maxSize = Infinity;
this.arrayed = true;
return true;

@@ -305,2 +317,3 @@ }

this.minSize = this.maxSize = parseInt(size);
this.arrayed = true;
return true;

@@ -311,2 +324,3 @@ }

this.maxSize = parseInt(RegExp.$1);
this.arrayed = true;
return true;

@@ -317,2 +331,3 @@ }

this.maxSize = Infinity;
this.arrayed = true;
return true;

@@ -323,2 +338,3 @@ }

this.maxSize = parseInt(RegExp.$2);
this.arrayed = true;
return true;

@@ -331,2 +347,3 @@ }

this.minSize = this.maxSize = size;
this.arrayed = true;
return true;

@@ -362,3 +379,3 @@ }

var DECOS = ['NULL', 'UNDEFINED'], i;
var DECOS = ['NULL', 'UNDEFINED', 'ABSENT'], i;

@@ -372,3 +389,10 @@ for (i = 1; i < arguments.length; i++) {

}
// @tag 20180222
else if (arguments[i] instanceof Absent) {
this.absent = true;
this.absentValue = arguments[i].value;
}
}
for (i = 0; i < decos.length; i++) {

@@ -380,2 +404,11 @@ var rawDeco = decos[i];

// 设置缺省值。
// 注意:为避免歧义,缺省值字面量中不得出现空格。
// @tag 20180222
if (/^=(.+)$/.test(rawDeco)) {
this.absent = true;
this.absentValue = eval(RegExp.$1);
continue;
}
// 普通修饰符不区分大小写。

@@ -397,2 +430,7 @@ decos[i] = decos[i].toUpperCase();

this.undef = has(decos, 'UNDEFINED');
// 参数是否可以缺席。
if (!this.absent) {
this.absent = has(decos, 'ABSENT');
}
}

@@ -422,10 +460,17 @@

var maxSize = 0;
var easy = true;
for (var i = 0, args; i < arguments.length; i++) {
args = (arguments[i] instanceof Array) ? arguments[i] : [ arguments[i] ];
params[i] = Param.parse.apply(null, args);
minSize += params[i].minSize;
maxSize += params[i].maxSize;
// @tag 20180222
// 如果参数允许缺省,则在整个实参列表中占据的最小长度为 0。
minSize += params[i].absent ? 0 : params[i].minSize;
// 如果形参可缺省,或者为多占位或可变长度,则不适用简易模式。
easy = easy && !( params[i].absent || params[i].arrayed );
}
// 指定匹配值组的最小和最大长度。
this.easy = easy;
this.minSize = minSize;

@@ -441,3 +486,3 @@ this.maxSize = maxSize;

* 判断值组是否合乎参数定义。
* @deprecated
* @deprecated 为了支持可变长度参数,用更复杂的 .parse() 方法取代。
*/

@@ -469,4 +514,4 @@ ParamList.prototype.satisfy = function(args) {

// ---------------------------
// 若整个参数组非可变长,则适用简易匹配逻辑。
if (this.minSize == this.maxSize) {
// 适用简易匹配逻辑。
if (this.easy) {
var matched = eachMatch(this.params, function(param, index) {

@@ -499,4 +544,4 @@ return param.satisfy(args[index]);

// ---------------------------
// 如果形式参数对应单个实参(不包括多于 1 的定长),则按简易逻辑处理。
if (param.minSize == param.maxSize == 1) {
// 如果形式参数对应单个实参且不可缺省,则按简易逻辑处理。
if (!param.absent && param.minSize == 1 && param.maxSize == 1) {
if (!param.satisfy(arg)) {

@@ -516,4 +561,17 @@ // 如果实参与形式参数不匹配,则终止后续匹配,整个参数表匹配失败。

// 如果剩余实参数量不足以匹配当前形式参数,则匹配失败。
// 如果剩余实参数量不足以匹配当前形式参数:
if (args.length - argCursor < param.minSize) {
// 若参数可缺省:
if (param.absent) {
// 使用缺省值替补。
newArgs.push(param.absentValue);
// 不消耗实参。
argCursor--;
// 当前形参匹配完毕。
continue;
}
// 否则当前形式参数匹配失败,整个参数表匹配失败。
return null;

@@ -524,2 +582,6 @@ }

var paramArgs = [];
var pushParamArg = function() {
if (param.arrayed) newArgs.push(paramArgs);
else newArgs.push(paramArgs[0]);
};

@@ -529,43 +591,76 @@ for (; argCursor < args.length && param.satisfy(args[argCursor]); argCursor++) {

}
argCursor--;
paramCursor++;
// 如当前形式参数匹配实参个数未达到最小值,则认为当前形式参数匹配失败,整个参数表匹配失败。
// 如当前形式参数匹配实参个数未达到最小值:
if (paramArgs.length < param.minSize) {
// 若参数可缺省:
if (param.absent) {
// 使用缺省值替补。
newArgs.push(param.absentValue);
// 回吐所有已消耗的实参。
argCursor -= paramArgs.length;
// 当前形参匹配完毕。
continue;
}
// 否则当前形式参数匹配失败,整个参数表匹配失败。
return null;
}
var restParams = params.slice(++paramCursor);
var restArgs = args.slice(argCursor);
var restParams = params.slice(paramCursor);
// 抵达匹配边界时,若仅匹配了最小数量的实参,或者已是最后一个形式参数,则直接固定。
if (paramArgs.length == param.minSize || restParams.length == 0) {
newArgs.push(paramArgs);
argCursor--;
// 抵达匹配边界时,若
// 仅匹配了最小数量的实参且该参数不可缺省,或者已是最后一个形式参数,
// 则直接固定参数值。
if (!param.absent && paramArgs.length == param.minSize || restParams.length == 0) {
pushParamArg();
continue;
}
// 否则,须尝试让贤。
else {
var restArgs = args.slice(argCursor + 1);
// 步步让贤,直到让无可让。
do {
var restNewArgs = matching(restArgs, restParams);
// 步步让贤,直到让无可让。
do {
var restNewArgs = matching(restArgs, restParams);
// 剩余参数匹配成功,则拼接匹配结果,整个参数表匹配成功。
if (restNewArgs != null) {
newArgs.push(paramArgs);
return newArgs.concat(restNewArgs);
// 剩余参数匹配成功,则拼接匹配结果,整个参数表匹配成功。
if (restNewArgs != null) {
pushParamArg();
newArgs = newArgs.concat(restNewArgs);
break;
}
// 如果已让无可让:
if (paramArgs.length == param.minSize) {
// 如果参数可以缺省,统统不要了,全给后续形参去。
if (param.absent) {
restArgs = paramArgs.concat(restArgs);
paramArgs = param.absentValue;
continue;
}
// 已无余量。
else if (paramArgs.length == 0) {
break;
}
else {
restArgs.unshift(paramArgs.pop());
}
} while (paramArgs.length >= param.minSize);
return null;
}
// 否则,就此罢了(liao)。
newArgs = null;
break;
}
else {
restArgs.unshift(paramArgs.pop());
}
} while (true);
// 行进至此,不成功,则成仁。
return newArgs;
}
// 此时,所有实参均已消耗完毕。
for (; newArgs.length < params.length; paramCursor++) {
if (params[paramCursor].minSize == 0) {
if (params[paramCursor].absent) {
newArgs.push(params[paramCursor].absentValue);
}
else if (params[paramCursor].minSize == 0) {
newArgs.push([]);

@@ -815,2 +910,4 @@ }

Overloader.absent = function(value) { return new Absent(value); };
// 输出所有自定义异常。

@@ -817,0 +914,0 @@ for (var name in ERR) {

{
"name": "overload2",
"version": "0.2.1",
"version": "0.3.0",
"description": "Elegant solution for function overloading in JavaScript",

@@ -10,3 +10,3 @@ "main": "overload2.js",

"scripts": {
"prepublishOnly": "mkdir -p dist && cp overload2.js dist && cd dist && uglifyjs --mangle --output overload2.min.js --source-map overload2.map overload2.js",
"prepublishOnly": "mkdir -p dist && cp overload2.js dist && cd dist && uglifyjs --mangle --output overload2.min.js --source-map filename=overload2.map overload2.js",
"test": "./node_modules/.bin/mocha"

@@ -13,0 +13,0 @@ },

@@ -301,2 +301,3 @@ # overload2

| undefined | If argument equals undefined (the place should be occupied), it matches the parameter. |
| absent | The argument may be absent (optional). See [example code](./example/optional.js) for more details. |

@@ -392,2 +393,11 @@ * new __overload2.Param__( string "\<alias\> \<decorator\> ..." )

* [Mutable Parameters](./example/mutable.js)
Explain how to define mutable parameters.
* [Optional Parameters](./example/optional.js)
Explain show how to indicate a param which may be absent (that means it is optional), and how to set the default value.
* [Parameter Decorators](./example/param-deco.js)
Introduce available decorators used to define a more complex parameter.
* [Advanced Usage](./example/advanced.js)

@@ -394,0 +404,0 @@ Use *overload2* in complex situations.

@@ -39,4 +39,4 @@ var MODULE_REQUIRE

DE([ 2, [ number, [] ] ], fn(number));
DE([ 2, [ number, [number] ] ], fn(number, number));
DE([ 2, [ number, [string,number] ] ], fn(number, string, number));
// DE([ 2, [ number, [number] ] ], fn(number, number));
// DE([ 2, [ number, [string,number] ] ], fn(number, string, number));
});

@@ -225,1 +225,20 @@

});
describe('Regurgitation', function() {
it('regurgitation', function() {
var fn = overload2()
.overload('number +', 'number 2', function(a, b) {
return a.length;
})
.overload('number +', function(a) {
return a.length;
})
;
assert.equal(1, fn(1));
assert.equal(2, fn(1, 2));
assert.equal(1, fn(1, 2, 3));
assert.equal(2, fn(1, 2, 3, 4));
assert.equal(3, fn(1, 2, 3, 4, 5));
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc