add mechanism for loading VM-specific functions (#289)

This commit is contained in:
Jeff Williams 2012-12-26 11:56:33 -08:00
parent ce8565f6e0
commit b786527ea4
8 changed files with 114 additions and 105 deletions

View File

@ -19,17 +19,6 @@ env = {
finish: null
},
/**
* The type of VM that is executing jsdoc:
*
* + {@link modules:jsdoc/util/vm.RHINO}: Mozilla Rhino.
* + {@link modules:jsdoc/util/vm.NODEJS}: Node.js.
*
* **Note**: Rhino is the only VM that is currently supported.
* @type string
*/
vm: require('jsdoc/util/vm').vm,
/**
The command line arguments passed into jsdoc.
@type Array
@ -44,6 +33,7 @@ env = {
/**
The absolute path to the base directory of the jsdoc application.
@private
@deprecated Use `__dirname` instead.
@type string
*/
@ -57,40 +47,12 @@ env = {
opts: {}
};
var args = Array.prototype.slice.call(arguments, 0);
env.dirname = (function() {
var dirname;
if ( require('jsdoc/util/vm').isRhino() ) {
// Rhino has no native way to get the base dirname of the current script,
// so this information must be manually passed in from the command line.
for (var i = 0; i < args.length; i++) {
if ( /^--dirname(?:=(.+?)(\/|\/\.)?)?$/i.test(args[i]) ) {
if (RegExp.$1) {
dirname = RegExp.$1; // last wins
args.splice(i--, 1); // remove --dirname opt from arguments
}
else {
dirname = args[i + 1];
args.splice(i--, 2);
}
}
}
} else {
// TODO: can't assign to __dirname here because on Rhino, it's not defined yet
// dirname = __dirname;
}
return dirname;
})();
// must be assigned after env.dirname, which modifies args
env.args = args;
args = undefined;
// TODO: consider always including an initializer for the current VM
if ( require('jsdoc/util/vm').isRhino() ) {
require('jsdoc/util/include')(env.dirname + '/rhino/rhino-shim.js');
}
// initialize the environment for the current JavaScript VM
(function(args) {
var vm = require('jsdoc/util/vm').vm;
// TODO: may need to move this file to support Node.js
require('initialize')[vm](args);
})( Array.prototype.slice.call(arguments, 0) );
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
@ -159,36 +121,22 @@ function main() {
/**
* If the current VM is Rhino, convert a path to a URI that meets the operating system's
* If required by the current VM, convert a path to a URI that meets the operating system's
* requirements. Otherwise, return the original path.
* @function
* @param {string} path The path to convert.
* @return {string} A URI that meets the operating system's requirements, or the original path.
*/
function pathToUri(_path) {
var result = _path;
if ( vm.isRhino() ) {
result = new java.io.File(result).toURI() + '';
}
return result;
}
var pathToUri = vm.getModule('jsdoc').pathToUri;
/**
* If the current VM is Rhino, convert a URI to a path that meets the operating system's
* If required by the current VM, convert a URI to a path that meets the operating system's
* requirements. Otherwise, assume the "URI" is really a path, and return the original path.
* @function
* @param {string} uri The URI to convert.
* @return {string} A path that meets the operating system's requirements.
*/
function uriToPath(uri) {
var result = uri;
if ( vm.isRhino() ) {
result = new java.io.File( new java.net.URI(result) ) + '';
}
return result;
}
var uriToPath = vm.getModule('jsdoc').uriToPath;
/**
Retrieve the fully resolved path to the requested template.
@ -223,7 +171,6 @@ function main() {
}
}
// this only messes with the path on Rhino
if (result) {
result = pathToUri(result);
}

40
lib/initialize.js Normal file
View File

@ -0,0 +1,40 @@
/*global env: true */
exports.rhino = function(args) {
var myGlobal = require('jsdoc/util/global');
// note: mutates args
function getDirname() {
var dirname;
// Rhino has no native way to get the base dirname of the current script,
// so this information must be manually passed in from the command line.
for (var i = 0; i < args.length; i++) {
if ( /^--dirname(?:=(.+?)(\/|\/\.)?)?$/i.test(args[i]) ) {
if (RegExp.$1) {
dirname = RegExp.$1; // last wins
args.splice(i--, 1); // remove --dirname opt from arguments
}
else {
dirname = args[i + 1];
args.splice(i--, 2);
}
}
}
return dirname;
}
myGlobal.__dirname = env.dirname = getDirname();
env.args = args;
require('jsdoc/util/include')(__dirname + '/rhino/rhino-shim.js');
};
exports.nodejs = function(args) {
throw new Error('Node.js is not currently supported!');
/*
env.dirname = __dirname;
env.args = args;
// TODO: add lib/ to the library paths
*/
};

View File

@ -1,22 +1,6 @@
/*global env: true, Packages: true */
var fs = require('fs');
var myGlobal = require('jsdoc/util/global');
var path = require('path');
var vm = require('jsdoc/util/vm');
function rhinoInclude(filepath) {
var cx = Packages.org.mozilla.javascript.Context.getCurrentContext();
Packages.org.mozilla.javascript.tools.shell.Main.processFile(cx, myGlobal, filepath);
}
// TODO: not tested
function nodejsInclude(filepath) {
var nodevm = require('vm');
var script = fs.readFileSync(filepath, 'utf8');
nodevm.runInNewContext(script, myGlobal, filepath);
}
/**
* Read and execute a JavaScript file in global scope.
* @private
@ -24,16 +8,10 @@ function nodejsInclude(filepath) {
* path relative to env.dirname.
*/
module.exports = function(filepath) {
// we use env.dirname because, on Rhino, we need this function before __dirname is defined
filepath = path.resolve(env.dirname, filepath);
filepath = path.resolve(__dirname, filepath);
try {
if ( vm.isRhino() ) {
rhinoInclude(filepath);
}
else {
nodejsInclude(filepath);
}
vm.getModule('jsdoc/util/include')(filepath);
}
catch (e) {
console.log('Cannot include ' + filepath + ': ' + e);

View File

@ -1,14 +1,22 @@
/*global Packages: true */
/**
* Helper functions for running JSDoc on multiple JavaScript VMs.
* Helper functions to enable JSDoc to run on multiple JavaScript virtual machines.
* @module jsdoc/util/vm
*/
// These strings represent JSDoc directory names; do not modify them!
// These strings represent directory names; do not modify them!
/** @private */
const RHINO = exports.RHINO = 'rhino';
/** @private */
const NODEJS = exports.NODEJS = 'nodejs';
exports.vm = (function() {
/**
* The JavaScript VM that is executing JSDoc:
*
* + `module:jsdoc/util/vm.RHINO`: Mozilla Rhino.
* + `module:jsdoc/util/vm.NODEJS`: Node.js (not currently supported).
*/
var vm = exports.vm = (function() {
if (Packages && typeof Packages === 'object' &&
Object.prototype.toString.call(Packages) === '[object JavaPackage]') {
return RHINO;
@ -16,14 +24,33 @@ exports.vm = (function() {
return NODEJS;
} else {
// unknown VM
throw new Error('Unable to identify the current JavaScript runtime.');
throw new Error('Unable to identify the current JavaScript VM.');
}
})();
exports.isRhino = function() {
return exports.vm === RHINO;
/**
* Load the VM-specific implementation of a module.
*
* @param {string} modulePath - The relative path to the module. Use the same format as when calling
* `require()`.
* @return {object} An object containing VM-specific functions for the requested module.
*/
exports.getModule = function(modulePath) {
return require( [__dirname, vm, modulePath].join('/') );
};
exports.isNodejs = function() {
return exports.vm === NODEJS;
/**
* Check whether Mozilla Rhino is running JSDoc.
* @return {boolean} Set to `true` if the current VM is Mozilla Rhino.
*/
exports.isRhino = function() {
return vm === RHINO;
};
/**
* Check whether Node.js is running JSDoc. (Node.js is not currently supported.)
* @return {boolean} Set to `true` if the current VM is Node.js.
*/
exports.isNodejs = function() {
return vm === NODEJS;
};

View File

@ -0,0 +1,8 @@
// TODO: not tested
module.exports = function(filepath) {
var fs = require('fs');
var vm = require('vm');
var script = fs.readFileSync(filepath, 'utf8');
vm.runInNewContext(script, global, filepath);
};

9
rhino/jsdoc.js Normal file
View File

@ -0,0 +1,9 @@
// Platform-specific functions to support jsdoc.js
exports.pathToUri = function(_path) {
return String( new java.io.File(_path).toURI() );
};
exports.uriToPath = function(uri) {
return String( new java.io.File(new java.net.URI(uri)) );
};

View File

@ -0,0 +1,7 @@
/*global Packages: true */
module.exports = function(filepath) {
var myGlobal = require('jsdoc/util/global');
var cx = Packages.org.mozilla.javascript.Context.getCurrentContext();
Packages.org.mozilla.javascript.tools.shell.Main.processFile(cx, myGlobal, filepath);
};

View File

@ -4,13 +4,6 @@
* to get JSDoc to run.
*/
/**
* Emulate Node.js globals.
* @see http://nodejs.org/api/globals.html
*/
__dirname = env.dirname;
/**
* Emulate DOM timeout/interval functions.
* @see https://developer.mozilla.org/en-US/docs/DOM/window#Methods