all files / src/ core.js

63.41% Statements 26/41
25% Branches 3/12
75% Functions 3/4
63.41% Lines 26/41
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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118                              1× 1× 1×   1× 1×   1× 1×         1× 1×               1×       1× 1× 1×                 1×                                 1×   2×                             2×           1× 2×   2× 2× 2×     2×           2×     2×             1×  
/*!
 * Copyright (C) 2017 Glayzzle (BSD3 License)
 * @authors https://github.com/glayzzle/php-transpiler/graphs/contributors
 * @url http://glayzzle.com
 */
'use strict';
 
/**
 * BAD DESIGN DISCLAIMER :
 * This class manage too much things (and will continue to grow)
 * until a day everything will the splitted ... need to implement
 * a prototype to grasp each concept and therefore will refactor
 * it in a clean code (it's bad and I know it)
 */
 
var path = require('path');
var fs = require('fs');
var extend = require('extend');
 
var Parser = require('php-parser');
var Transpiler = require('php-transpiler');
 
var Cache = require('./cache');
var Config = require('./config');
 
/**
 * @constructor Core
 */
var Core = function(options) {
  this.parser = new Parser({
    parser: {
      extractDoc: true
    },
    ast: {
      withPositions: true
    }
  });
  this.transpiler = new Transpiler({
    visitors: {},
    mode: 'body'
  });
  this.config = new Config();
  this.cache = new Cache();
  Iif (options) {
    extend(true, options, this);
  }
};
 
/**
 * Evaluate the specified code and returns its result
 * @return mixed
 */
Core.prototype.eval = function(code) {
  var fn = this.cache.getEval(code);
  if (!fn) {
    fn = new Function(
      '$php',
      this.transpiler.generate(
        this.parser.parseEval(code)
      )
    );
    this.cache.setEval(code, fn);
  }
  return fn;
};
 
/**
 * Resolves a filename
 */
Core.prototype.resolveFilename = function(filename) {
  // resolves the path with includes
  Iif (!path.isAbsolute(filename)) {
    if (filename in this.cache.stat.resolves) {
      // @fixme should flush it when changing includes
      return this.cache.stat.resolves[filename];
    }
    var includes = this.config.include_path;
    for(var i = 0; i < includes.length; i++) {
      var target = path.resolve(includes[i], filename);
      if (fs.existsSync(target)) {
        this.cache.stat.resolves[filename] = target;
        filename = target;
        break;
      }
    }
  }
  return filename;
}
 
/**
 * Includes the specified filename
 */
Core.prototype.include = function(filename) {
  filename = this.resolveFilename(filename);
  // load the callback
  var fn = this.cache.getScript(filename);
  Eif (!fn) {
    var code = fs.readFileSync(filename, {
      encoding: 'utf8'
    });
    fn = new Function(
      '$php',
      this.transpiler.generate(
        this.parser.parseCode(code, filename)
      )
    );
    this.cache.setScript(filename, fn);
  }
  // result response
  return {
    fn: fn,
    filename: filename
  };
};
 
// exports
module.exports = Core;