-p, --print print result of --eval
+ -c, --check syntax check script without executing
+
-i, --interactive always enter the REPL even if stdin
does not appear to be a terminal
--- /dev/null
+'use strict';
+
+module.exports.stripBOM = stripBOM;
+
+/**
+ * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
+ * because the buffer-to-string conversion in `fs.readFileSync()`
+ * translates it to FEFF, the UTF-16 BOM.
+ */
+function stripBOM(content) {
+ if (content.charCodeAt(0) === 0xFEFF) {
+ content = content.slice(1);
+ }
+ return content;
+}
const NativeModule = require('native_module');
const util = require('util');
+const internalModule = require('internal/module');
const internalUtil = require('internal/util');
const runInThisContext = require('vm').runInThisContext;
const assert = require('assert').ok;
};
-function stripBOM(content) {
- // Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
- // because the buffer-to-string conversion in `fs.readFileSync()`
- // translates it to FEFF, the UTF-16 BOM.
- if (content.charCodeAt(0) === 0xFEFF) {
- content = content.slice(1);
- }
- return content;
-}
-
-
// Native extension for .js
Module._extensions['.js'] = function(module, filename) {
var content = fs.readFileSync(filename, 'utf8');
- module._compile(stripBOM(content), filename);
+ module._compile(internalModule.stripBOM(content), filename);
};
Module._extensions['.json'] = function(module, filename) {
var content = fs.readFileSync(filename, 'utf8');
try {
- module.exports = JSON.parse(stripBOM(content));
+ module.exports = JSON.parse(internalModule.stripBOM(content));
} catch (err) {
err.message = filename + ': ' + err.message;
throw err;
'lib/zlib.js',
'lib/internal/child_process.js',
'lib/internal/freelist.js',
+ 'lib/internal/module.js',
'lib/internal/socket_list.js',
'lib/internal/repl.js',
'lib/internal/util.js',
static bool print_eval = false;
static bool force_repl = false;
+static bool syntax_check_only = false;
static bool trace_deprecation = false;
static bool throw_deprecation = false;
static bool abort_on_uncaught_exception = false;
READONLY_PROPERTY(process, "_print_eval", True(env->isolate()));
}
+ // -c, --check
+ if (syntax_check_only) {
+ READONLY_PROPERTY(process, "_syntax_check_only", True(env->isolate()));
+ }
+
// -i, --interactive
if (force_repl) {
READONLY_PROPERTY(process, "_forceRepl", True(env->isolate()));
" -v, --version print Node.js version\n"
" -e, --eval script evaluate script\n"
" -p, --print evaluate script and print result\n"
+ " -c, --check syntax check script without executing\n"
" -i, --interactive always enter the REPL even if stdin\n"
" does not appear to be a terminal\n"
" -r, --require module to preload (option can be repeated)\n"
}
args_consumed += 1;
local_preload_modules[preload_module_count++] = module;
+ } else if (strcmp(arg, "--check") == 0 || strcmp(arg, "-c") == 0) {
+ syntax_check_only = true;
} else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
force_repl = true;
} else if (strcmp(arg, "--no-deprecation") == 0) {
process.argv[1] = path.resolve(process.argv[1]);
var Module = NativeModule.require('module');
+
+ // check if user passed `-c` or `--check` arguments to Node.
+ if (process._syntax_check_only != null) {
+ var vm = NativeModule.require('vm');
+ var fs = NativeModule.require('fs');
+ var internalModule = NativeModule.require('internal/module');
+ // read the source
+ var filename = Module._resolveFilename(process.argv[1]);
+ var source = fs.readFileSync(filename, 'utf-8');
+ // remove shebang and BOM
+ source = internalModule.stripBOM(source.replace(/^\#\!.*/, ''));
+ // compile the script, this will throw if it fails
+ new vm.Script(source, {filename: filename, displayErrors: true});
+ process.exit(0);
+ }
+
startup.preloadModules();
if (global.v8debug &&
process.execArgv.some(function(arg) {
--- /dev/null
+var foo bar;
--- /dev/null
+#!/usr/bin/env node
+var foo bar;
--- /dev/null
+var foo = 'bar';
--- /dev/null
+#!/usr/bin/env node
+var foo = 'bar';
--- /dev/null
+'use strict';
+
+const assert = require('assert');
+const spawnSync = require('child_process').spawnSync;
+const path = require('path');
+
+const common = require('../common');
+
+var node = process.execPath;
+
+// test both sets of arguments that check syntax
+var syntaxArgs = [
+ ['-c'],
+ ['--check']
+];
+
+// test good syntax with and without shebang
+[
+ 'syntax/good_syntax.js',
+ 'syntax/good_syntax',
+ 'syntax/good_syntax_shebang.js',
+ 'syntax/good_syntax_shebang',
+].forEach(function(file) {
+ file = path.join(common.fixturesDir, file);
+
+ // loop each possible option, `-c` or `--check`
+ syntaxArgs.forEach(function(args) {
+ var _args = args.concat(file);
+ var c = spawnSync(node, _args, {encoding: 'utf8'});
+
+ // no output should be produced
+ assert.equal(c.stdout, '', 'stdout produced');
+ assert.equal(c.stderr, '', 'stderr produced');
+ assert.equal(c.status, 0, 'code == ' + c.status);
+ });
+});
+
+// test bad syntax with and without shebang
+[
+ 'syntax/bad_syntax.js',
+ 'syntax/bad_syntax',
+ 'syntax/bad_syntax_shebang.js',
+ 'syntax/bad_syntax_shebang'
+].forEach(function(file) {
+ file = path.join(common.fixturesDir, file);
+
+ // loop each possible option, `-c` or `--check`
+ syntaxArgs.forEach(function(args) {
+ var _args = args.concat(file);
+ var c = spawnSync(node, _args, {encoding: 'utf8'});
+
+ // no stdout should be produced
+ assert.equal(c.stdout, '', 'stdout produced');
+
+ // stderr should have a syntax error message
+ var match = c.stderr.match(/^SyntaxError: Unexpected identifier$/m);
+ assert(match, 'stderr incorrect');
+
+ assert.equal(c.status, 1, 'code == ' + c.status);
+ });
+});
+
+// test file not found
+[
+ 'syntax/file_not_found.js',
+ 'syntax/file_not_found'
+].forEach(function(file) {
+ file = path.join(common.fixturesDir, file);
+
+ // loop each possible option, `-c` or `--check`
+ syntaxArgs.forEach(function(args) {
+ var _args = args.concat(file);
+ var c = spawnSync(node, _args, {encoding: 'utf8'});
+
+ // no stdout should be produced
+ assert.equal(c.stdout, '', 'stdout produced');
+
+ // stderr should have a module not found error message
+ var match = c.stderr.match(/^Error: Cannot find module/m);
+ assert(match, 'stderr incorrect');
+
+ assert.equal(c.status, 1, 'code == ' + c.status);
+ });
+});