代码改变世界
2009-07-02 14:24
Cat Chen
阅读(754)
评论()
编辑
收藏
举报

(function()
{

Overload =
{};


var copySignature = function(signature)
{
var copy = [];

for (var i = 0; i < signature.length; i++)
{
copy.push(signature[i]);
}

if (signature.arguments)
{
copy.arguments = true;
}
return copy;
};

var inheritanceComparator = function(type1, type2)
{

if (type1 == type2)
{
return 0;

} else if (type2 == Overload.Any)
{
return 1;

} else if (type1 == Overload.Any)
{
return -1;

} else if (type1.prototype instanceof type2)
{
return 1;

} else if (type2.prototype instanceof type1)
{
return -1;

} else
{
return 0;
}
};

var overloadComparator = function(overload1, overload2)
{
var signature1Better = false;
var signature2Better = false;
var signature1 = overload1.signature;
var signature2 = overload2.signature;

if (!signature1.more && signature2.more)
{
signature1Better = true;
signature1 = copySignature(signature1);
signature1.length = signature2.length;

} else if (signature1.more && !signature2.more)
{
signature2Better = true;
signature2 = copySignature(signature2);
signature2.length = signature1.length;

} else if(signature1.more && signature2.more)
{

if (signature1.length > signature2.length)
{
signature2 = copySignature(signature2);

while (signature2.length < signature1.length)
{
signature2[signature2.length] = Overload.Any;
}

} else if (signature1.length < signature2.length)
{
signature1 = copySignature(signature1);

while (signature1.length < signature2.length)
{
signature1[signature1.length] = Overload.Any;
}
}
}

for (var i = 0; i < signature1.length; i++)
{
var comparison = inheritanceComparator(signature1[i], signature2[i]);

if (comparison > 0)
{
signature1Better = true;

} else if (comparison < 0)
{
signature2Better = true;
}
}

if (signature1Better && !signature2Better)
{
return 1;

} else if (!signature1Better && signature2Better)
{
return -1;

} else
{
return 0;
}
};

var matchSignature = function(argumentsArray, signature)
{

if (argumentsArray.length < signature.length)
{
return false;

} else if (argumentsArray.length > signature.length && !signature.more)
{
return false;
}

for (var i = 0; i < signature.length; i++)
{
if (!(signature[i] == Overload.Any
|| argumentsArray[i] instanceof signature[i]

|| argumentsArray[i].constructor == signature[i]))
{
return false;
}
}
return true;
};

Overload.create = function(overloadsArray)
{
var overloads = [];

var select = function(argumentsArray)
{
var matches = [];

for (var i = 0; i < overloads.length; i++)
{

if (matchSignature(argumentsArray, overloads[i].signature))
{
matches.push(overloads[i]);
}
}

switch (matches.length)
{
case 0:
return null;
case 1:
return matches[0]["function"];
default:
matches = matches.sort(overloadComparator);

if (overloadComparator(matches[matches.length - 1], matches[matches.length - 2]) > 0)
{
return matches[matches.length - 1]["function"];

} else
{
return null;
}
}
};

var overloaded = function()
{
var overload = select(arguments);

if (overload)
{
return overload.apply(this, arguments);

} else
{
throw "cannot select a proper overload";
}
};
overloaded.select = select;

overloaded.add = function(signature, overload)
{

if (signature instanceof Array)
{
signature = copySignature(signature);

} else if (signature.constructor == String)
{

if (signature.replace(/(^\s+|\s+$)/ig, "") == "")
{
signature = [];

} else
{
signature = signature.split(",");

for (var i = 0; i < signature.length; i++)
{
var typeExpression = signature[i].replace(/(^\s+|\s+$)/ig, "");
var type = null;

if (typeExpression == "*")
{
type = Overload.Any;

} else if (typeExpression == "...")
{
type = Overload.More;

} else
{

try
{
type = eval("(" + typeExpression + ")");

} catch (error)
{
throw "type expression cannot be evaluated: " + typeExpression;
}
}
signature[i] = type;
}
}

} else
{
throw "signature is neither a string nor an array";
}

for (var i = 0; i < signature.length; i++)
{

if (!(signature[i] instanceof Function))
{
throw "argument type should be a function";
}

if (i < signature.length - 1 && signature[i] == Overload.More)
{
throw "arguments type cannot be used in any argument except the last one";
}
}

if (signature[signature.length - 1] == Overload.More)
{
signature.length = signature.length - 1;
signature.more = true;
}

overloads.push(
{
"signature": signature,
"function": overload
});
return this;
};
return overloaded;
};

Overload.add = function(signature, overload)
{
return Overload.create().add(signature, overload);
};

Overload.Any = function any()
{
throw "this type is only an identifier and should not be instantiated"
};


Overload.More = function more()
{
throw "this type is only an identifier and should not be instantiated"
};
})();
点击右上角即可分享
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述