Plato on Github
Report Home
src/define/class/constructor.js
Maintainability
77.25
Lines of code
141
Difficulty
12.41
Estimated Errors
0.46
Function weight
By Complexity
By SLOC
/** * @file Class constructor * @since 0.1.6 */ /*#ifndef(UMD)*/ "use strict"; /*global _GpfClassDefinition*/ // Class definition /*global _gpfEmptyFunc*/ // An empty function /*global _gpfErrorDeclare*/ // Declare new gpf.Error names /*global _gpfFunctionBuild*/ // Build function from description and context /*global _gpfFunctionDescribe*/ // Extract function description /*global _gpfIsClass*/ // Check if the parameter is an ES6 class /*exported _gpfDefineClassConstructorAddCodeWrapper*/ // Adds a constructor code wrapper /*exported _gpfDefineGetClassSecuredConstructor*/ // Allocate a secured named constructor /*#endif*/ _gpfErrorDeclare("define/class/constructor", { /** * ### Summary * * This is a class constructor function, use with new * * ### Description * * Class constructors are not designed to be called without `new` * * @since 0.1.6 */ classConstructorFunction: "This is a class constructor function, use with new" }); Object.assign(_GpfClassDefinition.prototype, { /** * Resolved constructor * * @type {Function} * @since 0.1.6 */ _resolvedConstructor: _gpfEmptyFunc }); var _gpfDefineClassConstructorCodeWrappers = []; /** * Adds a constructor code wrapper * * @param {Function} codeWrapper Function receiving class definition and current code * @since 0.2.8 */ function _gpfDefineClassConstructorAddCodeWrapper (codeWrapper) { _gpfDefineClassConstructorCodeWrappers.push(codeWrapper); } function _gpfDefineGetClassSecuredConstructorGetES6ConstructionBody (classDefinition) { if (classDefinition._extend === classDefinition._resolvedConstructor) { return "var that = Reflect.construct(_classDef_._extend, arguments, _classDef_._instanceBuilder);\n"; } return "var that,\n" + " $super = function () {\n" + " that = Reflect.construct(_classDef_._extend, arguments, _classDef_._instanceBuilder);\n" + " },\n" + " hasOwnProperty = function (name) {\n" + " return !!that && Object.prototype.hasOwnProperty.call(that, name);\n" + " },\n" + " proxy = new Proxy({}, {\n" + " get: function (obj, property) {\n" + " if (property === \"hasOwnProperty\") {\n" + " return hasOwnProperty;\n" + " }\n" + " if (!that && property === \"$super\") {\n" + " return $super;\n" + " }\n" + " return that[property];\n" + " },\n" + " set: function (obj, property, value) {\n" + " if (property !== \"$super\") {\n" + " that[property] = value;\n" + " }\n" + " return true;\n" + " }\n" + " });\n" + "_classDef_._resolvedConstructor.apply(proxy, arguments);\n"; } function _gpfDefineGetClassSecuredConstructorGetMainConstructionPattern (classDefinition) { if (_gpfIsClass(classDefinition._extend)) { return { instance: "that", body: _gpfDefineGetClassSecuredConstructorGetES6ConstructionBody(classDefinition) }; } return { instance: "this", body: "_classDef_._resolvedConstructor.apply(this, arguments);" }; } function _gpfDefineGetClassSecuredConstructorBody (classDefinition) { var construction = _gpfDefineGetClassSecuredConstructorGetMainConstructionPattern(classDefinition), constructorBody = "if (!(this instanceof _classDef_._instanceBuilder)) gpf.Error.classConstructorFunction();\n" + _gpfDefineClassConstructorCodeWrappers.reduce(function (body, codeWrapper) { return codeWrapper(classDefinition, body, construction.instance); }, construction.body); if (construction.instance !== "this") { constructorBody += "\nreturn " + construction.instance + ";"; } return constructorBody; } function _gpfDefineGetClassSecuredConstructorDefinition (classDefinition) { return { name: classDefinition._name, parameters: _gpfFunctionDescribe(classDefinition._resolvedConstructor).parameters, body: _gpfDefineGetClassSecuredConstructorBody(classDefinition) }; } function _gpfDefineGetClassSecuredConstructorContext (classDefinition) { return { gpf: gpf, _classDef_: classDefinition }; } /** * Allocate a secured named constructor * * @param {_GpfClassDefinition} classDefinition Class definition * @return {Function} Secured named constructor * @gpf:closure * @since 0.1.6 */ function _gpfDefineGetClassSecuredConstructor (classDefinition) { return _gpfFunctionBuild(_gpfDefineGetClassSecuredConstructorDefinition(classDefinition), _gpfDefineGetClassSecuredConstructorContext(classDefinition)); }