all files / src/context/ classes.js

23.81% Statements 10/42
0% Branches 0/18
20% Functions 1/5
23.81% Lines 10/42
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100              1×           1× 1× 1× 1×             1×                                 1×                                           1×               1×                                                       1×  
/*!
 * Copyright (C) 2017 Glayzzle (BSD3 License)
 * @authors https://github.com/glayzzle/php-transpiler/graphs/contributors
 * @url http://glayzzle.com
 */
'use strict';
 
var Class = require('./reflection/class');
 
/**
 * Handles classes (from global context)
 * @constructor Classes
 */
var Classes = function(ctx) {
  this.items = {};
  this.loaders = [];
  this.ctx = ctx;
};
 
/**
 * Gets a class reflection
 * @return {Class}
 */
Classes.prototype.get = function(name) {
  if (!this.items.hasOwnProperty(name)) {
    // force autoload
    if (!this.has(name, true)) {
      this.ctx.php.trigger_error(
        'Unable find class: '+name
        , this.ctx.constant.get('E_ERROR')
      );
      return null;
    }
  }
  return this.items[name];
};
 
/**
 * Checks if the class can be found
 */
Classes.prototype.has = function(name, autoload) {
  if (this.items.hasOwnProperty(name)) {
    return true;
  } else if (autoload) {
    var found = false;
    for(var i = 0; i < this.ctx.loaders.length; i++) {
      var res = this.ctx.loaders[i](name);
      if (res === false) {
        return false;
      }
      if (res === true) {
        return this.items.hasOwnProperty(name);
      }
    }
  }
  return false;
};
 
/**
 * Initialize a new class instance
 * @return {Object}
 */
Classes.prototype.construct = function(name, args) {
  var item = this.get(name);
  return new item(args);
};
 
/**
 * Declares a new class
 */
Classes.prototype.declare = function(name, fn) {
 
  if (typeof name === 'function') {
    fn = name;
    name = fn.prototype.constructor.name;
  }
 
  if (!name) {
    throw new Error('Please provide a named function, or the name argument');
  }
 
  if (this.items.hasOwnProperty(name)) {
    this.ctx.php.trigger_error(
      'Cannot declare class '+name+', because the name is already in use'
      , this.ctx.constant.get('E_ERROR')
    );
    return this.items[name];
  }
 
  // register the class into the namespace scope
  var namespace = name.split('\\');
  var className = namespace.pop();
  namespace = this.ctx.namespace.get(namespace);
  this.items[name] = new Class(className, namespace);
  namespace.classes[className] = this.items[name];
  return this.items[name];
};
 
module.exports = Classes;