all files / src/context/ functions.js

75% Statements 39/52
57.69% Branches 15/26
66.67% Functions 4/6
80.85% Lines 38/47
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              1×           1× 1× 1×     1×         1×         1×     10×         10×         10× 10× 10× 1×     10× 10× 10×   10× 10× 10× 10×   10× 10× 10× 10×             1× 8× 8×   5×   3× 3× 3×   2×   3× 3× 3× 3×         3×       1×  
/*!
 * Copyright (C) 2017 Glayzzle (BSD3 License)
 * @authors https://github.com/glayzzle/php-transpiler/graphs/contributors
 * @url http://glayzzle.com
 */
'use strict';
 
var Fn = require('./reflection/function');
 
/**
 * Handles functions (from global context)
 * @constructor Functions
 */
var Functions = function(context) {
  this.items = {};
  this.context = context;
};
 
Functions.prototype.get = function(name) {
  if (name[0] !== '\\') name = '\\' + name;
  return this.items[name];
};
 
Functions.prototype.has = function(name) {
  if (name[0] !== '\\') name = '\\' + name;
  return name in this.items;
};
 
Functions.prototype.declare = function(name, args, type, fn) {
 
  // closure signature : (fn)
  Iif (typeof name === 'function') {
    fn = name;
    name = fn.name || '\\closure';
  }
  // signature : name, fn
  Iif (typeof args === 'function') {
    fn = args;
    args = [];
  }
  // defaults
  Iif (!args) args = [];
  Iif (!type) type = null;
  if (name[0] !== '\\') {
    name = this.context.namespace.current.fullName + '\\' + name;
  }
  // namespace resolution
  var nsPos = name.lastIndexOf('\\');
  var namespace = name.substring(0, nsPos + 1);
  var fnName = name.substring(nsPos + 1);
  // create instance
  var result = new Fn(fn, fnName);
  result.arguments = args;
  result.type = type;
  this.items[name] = result;
  // attach to namespace
  var namespace = this.context.namespace.get(namespace);
  namespace.functions[fnName] = result;
  result.namespace = namespace;
  return result;
};
 
/**
 * Gets a function callback
 * @return {function}
 */
Functions.prototype.callback = function(name, lookup, jit) {
  if (name[0] !== '\\') name = '\\' + name;
  if (name in this.items) {
    // bingo !
    return this.items[name].fn;
  } else {
    var self = this;
    var fn = function() {
      if (!(name in self.items) && lookup) {
        // try root namespace
        name = name.substring(name.lastIndexOf('\\'));
      }
      Eif (name in self.items) {
        fn = self.items[name].fn;
        jit(fn);
        return fn.apply(self, arguments);
      } else {
        throw new Error('Undefined function ' + name);
      }
    };
    return fn;
  }
};
 
module.exports = Functions;