diff options
Diffstat (limited to 'addon-sdk/source/lib/method')
-rw-r--r-- | addon-sdk/source/lib/method/.travis.yml | 5 | ||||
-rw-r--r-- | addon-sdk/source/lib/method/History.md | 55 | ||||
-rw-r--r-- | addon-sdk/source/lib/method/License.md | 18 | ||||
-rw-r--r-- | addon-sdk/source/lib/method/Readme.md | 117 | ||||
-rw-r--r-- | addon-sdk/source/lib/method/core.js | 225 | ||||
-rw-r--r-- | addon-sdk/source/lib/method/package.json | 41 | ||||
-rw-r--r-- | addon-sdk/source/lib/method/test/browser.js | 20 | ||||
-rw-r--r-- | addon-sdk/source/lib/method/test/common.js | 272 |
8 files changed, 0 insertions, 753 deletions
diff --git a/addon-sdk/source/lib/method/.travis.yml b/addon-sdk/source/lib/method/.travis.yml deleted file mode 100644 index 780731a47..000000000 --- a/addon-sdk/source/lib/method/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.4 - - 0.5 - - 0.6 diff --git a/addon-sdk/source/lib/method/History.md b/addon-sdk/source/lib/method/History.md deleted file mode 100644 index 95258c45f..000000000 --- a/addon-sdk/source/lib/method/History.md +++ /dev/null @@ -1,55 +0,0 @@ -# Changes - -## 1.0.2 / 2012-12-26 - - - Delegate to polymorphic methods from `.define` and `.implement` so, they - can be overidden. - -## 1.0.1 / 2012-11-11 - - - Fix issues with different `Error` types as they all inherit from - `Error`. - -## 1.0.0 / 2012-11-09 - - - Add browser test integration. - - Fix cross-browser incompatibilities & test failures. - - Add support for host objects. - - Add optional `hint` argument for method to ease debugging. - - Remove default implementation at definition time. - -## 0.1.1 / 2012-10-15 - - - Fix regression causing custom type implementation to be stored on objects. - -## 0.1.0 / 2012-10-15 - - - Remove dependency on name module. - - Implement fallback for engines that do not support ES5. - - Add support for built-in type extensions without extending their prototypes. - - Make API for default definitions more intuitive. - Skipping type argument now defines default: - - isFoo.define(function(value) { - return false - }) - - - Make exposed `define` and `implement` polymorphic. - - Removed dev dependency on swank-js. - - Primitive types `string, number, boolean` no longer inherit method - implementations from `Object`. - -## 0.0.3 / 2012-07-17 - - - Remove module boilerplate - -## 0.0.2 / 2012-06-26 - - - Name changes to make it less conflicting with other library conventions. - - Expose function version of `define` & `implement` methods. - - Expose `Null` and `Undefined` object holding implementations for an - associated types. - -## 0.0.1 / 2012-06-25 - - - Initial release diff --git a/addon-sdk/source/lib/method/License.md b/addon-sdk/source/lib/method/License.md deleted file mode 100644 index ed76489a3..000000000 --- a/addon-sdk/source/lib/method/License.md +++ /dev/null @@ -1,18 +0,0 @@ -Copyright 2012 Irakli Gozalishvili. All rights reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. diff --git a/addon-sdk/source/lib/method/Readme.md b/addon-sdk/source/lib/method/Readme.md deleted file mode 100644 index 9584c9160..000000000 --- a/addon-sdk/source/lib/method/Readme.md +++ /dev/null @@ -1,117 +0,0 @@ -# method - -[![Build Status](https://secure.travis-ci.org/Gozala/method.png)](http://travis-ci.org/Gozala/method) - -Library provides an API for defining polymorphic methods that dispatch on the -first argument type. This provides a powerful way for decouple abstraction -interface definition from an actual implementation per type, without risks -of interference with other libraries. - -### Motivation - - - Provide a high-performance, dynamic polymorphism construct as an - alternative to existing object methods that does not provides any - mechanics for guarding against name conflicts. - - Allow independent extension of types, and implementations of methods - on types, by different parties. - -## Install - - npm install method - -## Use - -```js -var method = require("method") - -// Define `isWatchable` method that can be implemented for any type. -var isWatchable = method("isWatchable") - -// If you call it on any object it will -// throw as nothing implements that method yet. -//isWatchable({}) // => Exception: method is not implemented - -// If you define private method on `Object.prototype` -// all objects will inherit it. -Object.prototype[isWatchable] = function() { - return false; -} - -isWatchable({}) // => false - - -// Although `isWatchable` property above will be enumerable and there for -// may damage some assumbtions made by other libraries. There for it"s -// recomended to use built-in helpers methods that will define extension -// without breaking assumbtions made by other libraries: - -isWatchable.define(Object, function() { return false }) - - -// There are primitive types in JS that won"t inherit methods from Object: -isWatchable(null) // => Exception: method is not implemented - -// One could either implement methods for such types: -isWatchable.define(null, function() { return false }) -isWatchable.define(undefined, function() { return false }) - -// Or simply define default implementation: -isWatchable.define(function() { return false }) - -// Alternatively default implementation may be provided at creation: -isWatchable = method(function() { return false }) - -// Method dispatches on an first argument type. That allows us to create -// new types with an alternative implementations: -function Watchable() {} -isWatchable.define(Watchable, function() { return true }) - -// This will make all `Watchable` instances watchable! -isWatchable(new Watchable()) // => true - -// Arbitrary objects can also be extended to implement given method. For example -// any object can simply made watchable: -function watchable(object) { - return isWatchable.implement(objct, function() { return true }) -} - -isWatchable(watchable({})) // => true - -// Full protocols can be defined with such methods: -var observers = "observers@" + module.filename -var watchers = method("watchers") -var watch = method("watch") -var unwatch = method("unwatch") - -watchers.define(Watchable, function(target) { - return target[observers] || (target[observers] = []) -}) - -watch.define(Watchable, function(target, watcher) { - var observers = watchers(target) - if (observers.indexOf(watcher) < 0) observers.push(watcher) - return target -}) -unwatch.define(Watchable, function(target, watcher) { - var observers = watchers(target) - var index = observers.indexOf(watcher) - if (observers.indexOf(watcher) >= 0) observers.unshift(watcher) - return target -}) - -// Define type Port that inherits form Watchable - -function Port() {} -Port.prototype = Object.create(Watchable.prototype) - -var emit = method("emit") -emit.define(Port, function(port, message) { - watchers(port).slice().forEach(function(watcher) { - watcher(message) - }) -}) - -var p = new Port() -watch(p, console.log) -emit(p, "hello world") // => info: "hello world" -``` diff --git a/addon-sdk/source/lib/method/core.js b/addon-sdk/source/lib/method/core.js deleted file mode 100644 index a6a5261e6..000000000 --- a/addon-sdk/source/lib/method/core.js +++ /dev/null @@ -1,225 +0,0 @@ -"use strict"; - -var defineProperty = Object.defineProperty || function(object, name, property) { - object[name] = property.value - return object -} - -// Shortcut for `Object.prototype.toString` for faster access. -var typefy = Object.prototype.toString - -// Map to for jumping from typeof(value) to associated type prefix used -// as a hash in the map of builtin implementations. -var types = { "function": "Object", "object": "Object" } - -// Array is used to save method implementations for the host objects in order -// to avoid extending them with non-primitive values that could cause leaks. -var host = [] -// Hash map is used to save method implementations for builtin types in order -// to avoid extending their prototypes. This also allows to share method -// implementations for types across diff contexts / frames / compartments. -var builtin = {} - -function Primitive() {} -function ObjectType() {} -ObjectType.prototype = new Primitive() -function ErrorType() {} -ErrorType.prototype = new ObjectType() - -var Default = builtin.Default = Primitive.prototype -var Null = builtin.Null = new Primitive() -var Void = builtin.Void = new Primitive() -builtin.String = new Primitive() -builtin.Number = new Primitive() -builtin.Boolean = new Primitive() - -builtin.Object = ObjectType.prototype -builtin.Error = ErrorType.prototype - -builtin.EvalError = new ErrorType() -builtin.InternalError = new ErrorType() -builtin.RangeError = new ErrorType() -builtin.ReferenceError = new ErrorType() -builtin.StopIteration = new ErrorType() -builtin.SyntaxError = new ErrorType() -builtin.TypeError = new ErrorType() -builtin.URIError = new ErrorType() - - -function Method(hint) { - /** - Private Method is a callable private name that dispatches on the first - arguments same named Method: - - method(object, ...rest) => object[method](...rest) - - Optionally hint string may be provided that will be used in generated names - to ease debugging. - - ## Example - - var foo = Method() - - // Implementation for any types - foo.define(function(value, arg1, arg2) { - // ... - }) - - // Implementation for a specific type - foo.define(BarType, function(bar, arg1, arg2) { - // ... - }) - **/ - - // Create an internal unique name if `hint` is provided it is used to - // prefix name to ease debugging. - var name = (hint || "") + "#" + Math.random().toString(32).substr(2) - - function dispatch(value) { - // Method dispatches on type of the first argument. - // If first argument is `null` or `void` associated implementation is - // looked up in the `builtin` hash where implementations for built-ins - // are stored. - var type = null - var method = value === null ? Null[name] : - value === void(0) ? Void[name] : - // Otherwise attempt to use method with a generated private - // `name` that is supposedly in the prototype chain of the - // `target`. - value[name] || - // Otherwise assume it's one of the built-in type instances, - // in which case implementation is stored in a `builtin` hash. - // Attempt to find a implementation for the given built-in - // via constructor name and method name. - ((type = builtin[(value.constructor || "").name]) && - type[name]) || - // Otherwise assume it's a host object. For host objects - // actual method implementations are stored in the `host` - // array and only index for the implementation is stored - // in the host object's prototype chain. This avoids memory - // leaks that otherwise could happen when saving JS objects - // on host object. - host[value["!" + name] || void(0)] || - // Otherwise attempt to lookup implementation for builtins by - // a type of the value. This basically makes sure that all - // non primitive values will delegate to an `Object`. - ((type = builtin[types[typeof(value)]]) && type[name]) - - - // If method implementation for the type is still not found then - // just fallback for default implementation. - method = method || Default[name] - - - // If implementation is still not found (which also means there is no - // default) just throw an error with a descriptive message. - if (!method) throw TypeError("Type does not implements method: " + name) - - // If implementation was found then just delegate. - return method.apply(method, arguments) - } - - // Make `toString` of the dispatch return a private name, this enables - // method definition without sugar: - // - // var method = Method() - // object[method] = function() { /***/ } - dispatch.toString = function toString() { return name } - - // Copy utility methods for convenient API. - dispatch.implement = implementMethod - dispatch.define = defineMethod - - return dispatch -} - -// Create method shortcuts form functions. -var defineMethod = function defineMethod(Type, lambda) { - return define(this, Type, lambda) -} -var implementMethod = function implementMethod(object, lambda) { - return implement(this, object, lambda) -} - -// Define `implement` and `define` polymorphic methods to allow definitions -// and implementations through them. -var implement = Method("implement") -var define = Method("define") - - -function _implement(method, object, lambda) { - /** - Implements `Method` for the given `object` with a provided `implementation`. - Calling `Method` with `object` as a first argument will dispatch on provided - implementation. - **/ - return defineProperty(object, method.toString(), { - enumerable: false, - configurable: false, - writable: false, - value: lambda - }) -} - -function _define(method, Type, lambda) { - /** - Defines `Method` for the given `Type` with a provided `implementation`. - Calling `Method` with a first argument of this `Type` will dispatch on - provided `implementation`. If `Type` is a `Method` default implementation - is defined. If `Type` is a `null` or `undefined` `Method` is implemented - for that value type. - **/ - - // Attempt to guess a type via `Object.prototype.toString.call` hack. - var type = Type && typefy.call(Type.prototype) - - // If only two arguments are passed then `Type` is actually an implementation - // for a default type. - if (!lambda) Default[method] = Type - // If `Type` is `null` or `void` store implementation accordingly. - else if (Type === null) Null[method] = lambda - else if (Type === void(0)) Void[method] = lambda - // If `type` hack indicates built-in type and type has a name us it to - // store a implementation into associated hash. If hash for this type does - // not exists yet create one. - else if (type !== "[object Object]" && Type.name) { - var Bulitin = builtin[Type.name] || (builtin[Type.name] = new ObjectType()) - Bulitin[method] = lambda - } - // If `type` hack indicates an object, that may be either object or any - // JS defined "Class". If name of the constructor is `Object`, assume it's - // built-in `Object` and store implementation accordingly. - else if (Type.name === "Object") - builtin.Object[method] = lambda - // Host objects are pain!!! Every browser does some crazy stuff for them - // So far all browser seem to not implement `call` method for host object - // constructors. If that is a case here, assume it's a host object and - // store implementation in a `host` array and store `index` in the array - // in a `Type.prototype` itself. This avoids memory leaks that could be - // caused by storing JS objects on a host objects. - else if (Type.call === void(0)) { - var index = host.indexOf(lambda) - if (index < 0) index = host.push(lambda) - 1 - // Prefix private name with `!` so it can be dispatched from the method - // without type checks. - implement("!" + method, Type.prototype, index) - } - // If Got that far `Type` is user defined JS `Class`. Define private name - // as hidden property on it's prototype. - else - implement(method, Type.prototype, lambda) -} - -// And provided implementations for a polymorphic equivalents. -_define(define, _define) -_define(implement, _implement) - -// Define exports on `Method` as it's only thing being exported. -Method.implement = implement -Method.define = define -Method.Method = Method -Method.method = Method -Method.builtin = builtin -Method.host = host - -module.exports = Method diff --git a/addon-sdk/source/lib/method/package.json b/addon-sdk/source/lib/method/package.json deleted file mode 100644 index 7bb004e28..000000000 --- a/addon-sdk/source/lib/method/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "method", - "id": "method", - "version": "1.0.2", - "description": "Functional polymorphic method dispatch", - "keywords": [ - "method", - "dispatch", - "protocol", - "polymorphism", - "type dispatch" - ], - "author": "Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)", - "homepage": "https://github.com/Gozala/method", - "main": "./core.js", - "repository": { - "type": "git", - "url": "https://github.com/Gozala/method.git", - "web": "https://github.com/Gozala/method" - }, - "bugs": { - "url": "http://github.com/Gozala/method/issues/" - }, - "devDependencies": { - "test": "~0.x.0", - "repl-utils": "~2.0.1", - "phantomify": "~0.1.0" - }, - "scripts": { - "test": "npm run test-node && npm run test-browser", - "test-browser": "node ./node_modules/phantomify/bin/cmd.js ./test/browser.js", - "test-node": "node ./test/common.js", - "repl": "node node_modules/repl-utils" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/Gozala/method/License.md" - } - ] -} diff --git a/addon-sdk/source/lib/method/test/browser.js b/addon-sdk/source/lib/method/test/browser.js deleted file mode 100644 index 7c8e6cd52..000000000 --- a/addon-sdk/source/lib/method/test/browser.js +++ /dev/null @@ -1,20 +0,0 @@ -"use strict"; - -exports["test common"] = require("./common") - -var Method = require("../core") - -exports["test host objects"] = function(assert) { - var isElement = Method("is-element") - isElement.define(function() { return false }) - - isElement.define(Element, function() { return true }) - - assert.notDeepEqual(typeof(Element.prototype[isElement]), "number", - "Host object's prototype is extended with a number value") - - assert.ok(!isElement({}), "object is not an Element") - assert.ok(document.createElement("div"), "Element is an element") -} - -require("test").run(exports) diff --git a/addon-sdk/source/lib/method/test/common.js b/addon-sdk/source/lib/method/test/common.js deleted file mode 100644 index 0418c3a23..000000000 --- a/addon-sdk/source/lib/method/test/common.js +++ /dev/null @@ -1,272 +0,0 @@ -"use strict"; - -var Method = require("../core") - -function type(value) { - return Object.prototype.toString.call(value). - split(" "). - pop(). - split("]"). - shift(). - toLowerCase() -} - -var values = [ - null, // 0 - undefined, // 1 - Infinity, // 2 - NaN, // 3 - 5, // 4 - {}, // 5 - Object.create({}), // 6 - Object.create(null), // 7 - [], // 8 - /foo/, // 9 - new Date(), // 10 - Function, // 11 - function() {}, // 12 - true, // 13 - false, // 14 - "string" // 15 -] - -function True() { return true } -function False() { return false } - -var trues = values.map(True) -var falses = values.map(False) - -exports["test throws if not implemented"] = function(assert) { - var method = Method("nope") - - assert.throws(function() { - method({}) - }, /not implement/i, "method throws if not implemented") - - assert.throws(function() { - method(null) - }, /not implement/i, "method throws on null") -} - -exports["test all types inherit from default"] = function(assert) { - var isImplemented = Method("isImplemented") - isImplemented.define(function() { return true }) - - values.forEach(function(value) { - assert.ok(isImplemented(value), - type(value) + " inherits deafult implementation") - }) -} - -exports["test default can be implemented later"] = function(assert) { - var isImplemented = Method("isImplemented") - isImplemented.define(function() { - return true - }) - - values.forEach(function(value) { - assert.ok(isImplemented(value), - type(value) + " inherits deafult implementation") - }) -} - -exports["test dispatch not-implemented"] = function(assert) { - var isDefault = Method("isDefault") - values.forEach(function(value) { - assert.throws(function() { - isDefault(value) - }, /not implement/, type(value) + " throws if not implemented") - }) -} - -exports["test dispatch default"] = function(assert) { - var isDefault = Method("isDefault") - - // Implement default - isDefault.define(True) - assert.deepEqual(values.map(isDefault), trues, - "all implementation inherit from default") - -} - -exports["test dispatch null"] = function(assert) { - var isNull = Method("isNull") - - // Implement default - isNull.define(False) - isNull.define(null, True) - assert.deepEqual(values.map(isNull), - [ true ]. - concat(falses.slice(1)), - "only null gets methods defined for null") -} - -exports["test dispatch undefined"] = function(assert) { - var isUndefined = Method("isUndefined") - - // Implement default - isUndefined.define(False) - isUndefined.define(undefined, True) - assert.deepEqual(values.map(isUndefined), - [ false, true ]. - concat(falses.slice(2)), - "only undefined gets methods defined for undefined") -} - -exports["test dispatch object"] = function(assert) { - var isObject = Method("isObject") - - // Implement default - isObject.define(False) - isObject.define(Object, True) - assert.deepEqual(values.map(isObject), - [ false, false, false, false, false ]. - concat(trues.slice(5, 13)). - concat([false, false, false]), - "all values except primitives inherit Object methods") - -} - -exports["test dispatch number"] = function(assert) { - var isNumber = Method("isNumber") - isNumber.define(False) - isNumber.define(Number, True) - - assert.deepEqual(values.map(isNumber), - falses.slice(0, 2). - concat(true, true, true). - concat(falses.slice(5)), - "all numbers inherit from Number method") -} - -exports["test dispatch string"] = function(assert) { - var isString = Method("isString") - isString.define(False) - isString.define(String, True) - - assert.deepEqual(values.map(isString), - falses.slice(0, 15). - concat(true), - "all strings inherit from String method") -} - -exports["test dispatch function"] = function(assert) { - var isFunction = Method("isFunction") - isFunction.define(False) - isFunction.define(Function, True) - - assert.deepEqual(values.map(isFunction), - falses.slice(0, 11). - concat(true, true). - concat(falses.slice(13)), - "all functions inherit from Function method") -} - -exports["test dispatch date"] = function(assert) { - var isDate = Method("isDate") - isDate.define(False) - isDate.define(Date, True) - - assert.deepEqual(values.map(isDate), - falses.slice(0, 10). - concat(true). - concat(falses.slice(11)), - "all dates inherit from Date method") -} - -exports["test dispatch RegExp"] = function(assert) { - var isRegExp = Method("isRegExp") - isRegExp.define(False) - isRegExp.define(RegExp, True) - - assert.deepEqual(values.map(isRegExp), - falses.slice(0, 9). - concat(true). - concat(falses.slice(10)), - "all regexps inherit from RegExp method") -} - -exports["test redefine for descendant"] = function(assert) { - var isFoo = Method("isFoo") - var ancestor = {} - isFoo.implement(ancestor, function() { return true }) - var descendant = Object.create(ancestor) - isFoo.implement(descendant, function() { return false }) - - assert.ok(isFoo(ancestor), "defined on ancestor") - assert.ok(!isFoo(descendant), "overrided for descendant") -} - -exports["test on custom types"] = function(assert) { - function Bar() {} - var isBar = Method("isBar") - - isBar.define(function() { return false }) - isBar.define(Bar, function() { return true }) - - assert.ok(!isBar({}), "object is get's default implementation") - assert.ok(isBar(new Bar()), "Foo type objects get own implementation") - - var isObject = Method("isObject") - isObject.define(function() { return false }) - isObject.define(Object, function() { return true }) - - assert.ok(isObject(new Bar()), "foo inherits implementation from object") - - - isObject.define(Bar, function() { return false }) - - assert.ok(!isObject(new Bar()), - "implementation inherited form object can be overrided") -} - - -exports["test error types"] = function(assert) { - var isError = Method("isError") - isError.define(function() { return false }) - isError.define(Error, function() { return true }) - - assert.ok(isError(Error("boom")), "error is error") - assert.ok(isError(TypeError("boom")), "type error is an error") - assert.ok(isError(EvalError("boom")), "eval error is an error") - assert.ok(isError(RangeError("boom")), "range error is an error") - assert.ok(isError(ReferenceError("boom")), "reference error is an error") - assert.ok(isError(SyntaxError("boom")), "syntax error is an error") - assert.ok(isError(URIError("boom")), "URI error is an error") -} - -exports["test override define polymorphic method"] = function(assert) { - var define = Method.define - var implement = Method.implement - - var fn = Method("fn") - var methods = {} - implement(define, fn, function(method, label, implementation) { - methods[label] = implementation - }) - - function foo() {} - - define(fn, "foo-case", foo) - - assert.equal(methods["foo-case"], foo, "define set property") -} - -exports["test override define via method API"] = function(assert) { - var define = Method.define - var implement = Method.implement - - var fn = Method("fn") - var methods = {} - define.implement(fn, function(method, label, implementation) { - methods[label] = implementation - }) - - function foo() {} - - define(fn, "foo-case", foo) - - assert.equal(methods["foo-case"], foo, "define set property") -} - -require("test").run(exports) |