<commit_before>/**
 * The proto factory is responsible for creating instances of defined objects using the config tree
 */
define("inverted/ProtoFactory", [ "inverted/DependencyTree", "inverted/Util" ], function(DependencyTree, Util) {

    "use strict";

    /**
     * Create a new ProtoFactory with config
     * 
     * @constructor
     * @param {Object} config
     */
    var ProtoFactory = function(config) {

        this.config = config;
        this.appContext = null;

        this.injectAppContext = this.config.injectAppContext === true ? true : false;

        //cache of loaded dependencies
        this.moduleMap = {};
    };


    /**
     * Adds dependency id to object/function mappings to the internal dependency map
     * @param {Object} map   adds a map of dependencies to the existing dependency map cache
     */
    ProtoFactory.prototype.addLoadedModules = function(map) {

        //joins the objects
        for(var depId in map) {
            if(map.hasOwnProperty(depId)) {
                this.moduleMap[depId] = map[depId];
            }
        }
    };

    /**
     * Gets a proto given an id
     * The parsing also looks for an optional interface id using square brackets notation. E.g. protoId[interfaceId]
     * 
     * @param {String} protoRef a proto reference string
     * @param {Object} depTree
     * @return {Object} A reference to a javascript object
     */
    ProtoFactory.prototype.getProto = function(protoRef, depTree) {

        depTree = depTree || new DependencyTree();

        var protoData = Util.parseProtoReference(protoRef);
        var protoConf = this.getProtoConfig(protoData.protoId);

        var instance = null;
        var nextNode = depTree.addChild();

        // for static just get a reference
        if(protoConf.scope === "static") {

            if(typeof protoConf.module === "string") {
                instance = this.moduleMap[protoConf.module];
            }
        // create an instance if not singleton or
        // singleton and no instance created yet (lazy loaded singletons)
        } else if((!protoConf.scope || protoConf.scope !== "singleton") ||
                (protoConf.scope === "singleton" && !protoConf.instance)) {

            var injectAppContext =
                this.injectAppContext === true && protoConf.injectAppContext !== false ||
                this.injectAppContext !== true && protoConf.injectAppContext === true;

            instance = this._createInstance(protoData.protoId, protoConf, protoData.interfaces, injectAppContext, nextNode);

            // save instance if singleton
            if(protoConf.scope && protoConf.scope === "singleton") {
                protoConf.instance = instance;
            }
        }
        // its a singleton and instance has already been created
        else {
            instance = protoConf.instance;
        }

        return instance;
    };

    /**
     * Uses factory config to create a new instance
     *
     * @param {String} protoId {String|Object} this might be a string or an proto
     * @param {Object} protoConf
     * @param {Array} interfaces
     * @param {Boolean} injectAppContext
     * @param {Object} depTree
     * @return {Object}
     */
    ProtoFactory.prototype._createInstance = function(protoId, protoConf, interfaces, injectAppContext, depTree) {

        var instance = null;
        var proto = this.moduleMap[protoConf.module];

        //check for circular dependencies
        var circularConf = depTree.checkForCircular(protoId);
        if(circularConf) {
            //TODO: need to inject circular references
            depTree.addProto(protoId, circularConf.instance);
            return circularConf.instance;
        }

        // constructor injection
        var args = this._createArgs(protoConf.args, depTree);

        // inheritance
        if(protoConf.extendsRef) {
            this._extendProto(proto, this.getProto(protoConf.extendsRef, depTree));
        }

        //check implementation
        //if an interface id specified, check the implementation
        if(interfaces) {
            this._checkImplements(protoId, proto.prototype, interfaces);
        }

        // ugly but works. would like a better way
        switch(args.length) {
        case 0:
            instance = new proto();
            break;
        case 1:
            instance = new proto(args[0]);
            break;
        case 2:
            instance = new proto(args[0], args[1]);
            break;
        case 3:
            instance = new proto(args[0], args[1], args[2]);
            break;
        case 4:
            instance = new proto(args[0], args[1], args[2], args[3]);
            break;
        case 5:
            instance = new proto(args[0], args[1], args[2], args[3], args[4]);
            break;
        case 6:
            instance = new proto(args[0], args[1], args[2], args[3], args[4], args[5]);
            break;
        case 7:
            instance = new proto(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
            break;
        case 8:
            instance = new proto(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
            break;
        case 9:
            instance = new proto(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
            break;
        case 10:
            instance = new proto(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]);
            break;
        default:
            throw Util.createError("Could not instantiate proto. Instances have a 10 arg limit");
        }

        //add the dependency to the dependency tree.<commit_msg>Improved code for creating new instances<commit_after>/**
 * The proto factory is responsible for creating instances of defined objects using the config tree
 */
define("inverted/ProtoFactory", [ "inverted/DependencyTree", "inverted/Util" ], function(DependencyTree, Util) {

    "use strict";

    /**
     * Create a new ProtoFactory with config
     * 
     * @constructor
     * @param {Object} config
     */
    var ProtoFactory = function(config) {

        this.config = config;
        this.appContext = null;

        this.injectAppContext = this.config.injectAppContext === true ? true : false;

        //cache of loaded dependencies
        this.moduleMap = {};
    };


    /**
     * Adds dependency id to object/function mappings to the internal dependency map
     * @param {Object} map   adds a map of dependencies to the existing dependency map cache
     */
    ProtoFactory.prototype.addLoadedModules = function(map) {

        //joins the objects
        for(var depId in map) {
            if(map.hasOwnProperty(depId)) {
                this.moduleMap[depId] = map[depId];
            }
        }
    };

    /**
     * Gets a proto given an id
     * The parsing also looks for an optional interface id using square brackets notation. E.g. protoId[interfaceId]
     * 
     * @param {String} protoRef a proto reference string
     * @param {Object} depTree
     * @return {Object} A reference to a javascript object
     */
    ProtoFactory.prototype.getProto = function(protoRef, depTree) {

        depTree = depTree || new DependencyTree();

        var protoData = Util.parseProtoReference(protoRef);
        var protoConf = this.getProtoConfig(protoData.protoId);

        var instance = null;
        var nextNode = depTree.addChild();

        // for static just get a reference
        if(protoConf.scope === "static") {

            if(typeof protoConf.module === "string") {
                instance = this.moduleMap[protoConf.module];
            }
        // create an instance if not singleton or
        // singleton and no instance created yet (lazy loaded singletons)
        } else if((!protoConf.scope || protoConf.scope !== "singleton") ||
                (protoConf.scope === "singleton" && !protoConf.instance)) {

            var injectAppContext =
                this.injectAppContext === true && protoConf.injectAppContext !== false ||
                this.injectAppContext !== true && protoConf.injectAppContext === true;

            instance = this._createInstance(protoData.protoId, protoConf, protoData.interfaces, injectAppContext, nextNode);

            // save instance if singleton
            if(protoConf.scope && protoConf.scope === "singleton") {
                protoConf.instance = instance;
            }
        }
        // its a singleton and instance has already been created
        else {
            instance = protoConf.instance;
        }

        return instance;
    };

    /**
     * Uses factory config to create a new instance
     *
     * @param {String} protoId {String|Object} this might be a string or an proto
     * @param {Object} protoConf
     * @param {Array} interfaces
     * @param {Boolean} injectAppContext
     * @param {Object} depTree
     * @return {Object}
     */
    ProtoFactory.prototype._createInstance = function(protoId, protoConf, interfaces, injectAppContext, depTree) {

        var instance = null;
        var proto = this.moduleMap[protoConf.module];

        //check for circular dependencies
        var circularConf = depTree.checkForCircular(protoId);
        if(circularConf) {
            //TODO: need to inject circular references
            depTree.addProto(protoId, circularConf.instance);
            return circularConf.instance;
        }

        // constructor injection
        var args = this._createArgs(protoConf.args, depTree);

        // inheritance
        if(protoConf.extendsRef) {
            this._extendProto(proto, this.getProto(protoConf.extendsRef, depTree));
        }

        //check implementation
        //if an interface id specified, check the implementation
        if(interfaces) {
            this._checkImplements(protoId, proto.prototype, interfaces);
        }

	    //magic constructor fn
	    var construct = function(constructorFn, args) {

		    var newConstructorFn = function () {
			    constructorFn.apply(this, args);
		    };
		    newConstructorFn.prototype = constructorFn.prototype;
		    return new newConstructorFn();
	    };
	    instance = construct(proto, args);

        //add the dependency to the dependency tree.
{'fraction_non_alphanumeric': 0.10643252158727079, 'fraction_numerical': 0.006694479479965073, 'mean_word_length': 2.1600245248313916, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4865277', 'n_tokens_mistral': 2790, 'n_tokens_neox': 2656, 'n_words': 788}