kopia lustrzana https://github.com/c9/core
Merge remote-tracking branch 'origin/master' into language-library-ui
Conflicts: npm-shrinkwrap.json plugins/c9.ide.language.javascript.tern/worker/tern_worker.js plugins/c9.ide.language/language.js plugins/c9.ide.language/worker.jspull/242/head
commit
4fc8c26766
|
@ -48,5 +48,5 @@ rules:
|
|||
space-in-parens: [1, "never"]
|
||||
space-return-throw-case: [1, "always"]
|
||||
// space-before-function-paren: [3, {"named": "never", "anonymous": "never"}]
|
||||
spaced-line-comment: 3
|
||||
spaced-comment: 3
|
||||
// valid-jsdoc: [1, { requireReturn: false, requireParamDescription: false, prefer: { "return": "return" } }]
|
||||
|
|
|
@ -53,15 +53,6 @@ module.exports.makeLocal = function(config, options) {
|
|||
config[i].path = join(settingDir, "/metadata");
|
||||
config[i].changeCheckInterval = 2000;
|
||||
}
|
||||
else if (config[i].packagePath == "plugins/c9.ide.feedback/feedback") {
|
||||
config[i].screenshotSupport = false;
|
||||
}
|
||||
// else if (config[i].packagePath == "plugins/c9.ide.feedback/feedback") {
|
||||
// config[i] = {
|
||||
// packagePath : "plugins/c9.ide.help/help",
|
||||
// staticPrefix : options.staticPrefix + "/plugins/c9.ide.help"
|
||||
// };
|
||||
// }
|
||||
|
||||
else if (config[i].packagePath == "plugins/c9.core/c9") {
|
||||
config[i].local = true;
|
||||
|
@ -76,8 +67,6 @@ module.exports.makeLocal = function(config, options) {
|
|||
config[i].projectConfigPath = join(settingDir, "");
|
||||
config[i].userConfigPath = join(settingDir, "");
|
||||
config[i].stateConfigPath = join(settingDir, "");
|
||||
} else if (config[i].packagePath == "plugins/c9.ide.log/log" && !c9Ws) {
|
||||
config[i].source = "desktop";
|
||||
} else if (config[i].packagePath == "plugins/c9.ide.info/info" && c9Ws) {
|
||||
config[i].packagePath = "plugins/c9.ide.local/info";
|
||||
} else if (config[i].packagePath == "plugins/c9.ide.ui/menus" && c9Ws) {
|
||||
|
@ -140,7 +129,6 @@ module.exports.makeLocal = function(config, options) {
|
|||
"plugins/c9.ide.newresource/open": true,
|
||||
"plugins/c9.ide.info/info": true,
|
||||
// "plugins/c9.ide.login/login": true,
|
||||
"plugins/c9.ide.feedback/nps": true,
|
||||
"plugins/c9.ide.download/download": true
|
||||
};
|
||||
|
||||
|
|
|
@ -399,7 +399,10 @@ module.exports = function(options) {
|
|||
"plugins/c9.ide.language.javascript.tern/ui",
|
||||
"plugins/c9.ide.language.javascript.tern/architect_resolver",
|
||||
"plugins/c9.ide.language.javascript.eslint/eslint",
|
||||
"plugins/c9.ide.language.python/python",
|
||||
{
|
||||
packagePath: "plugins/c9.ide.language.python/python",
|
||||
pythonPath: "/usr/local/lib/python2.7/dist-packages:/usr/local/lib/python3.4/dist-packages",
|
||||
},
|
||||
{
|
||||
packagePath: "plugins/c9.ide.language.jsonalyzer/jsonalyzer",
|
||||
extendToken: extendToken,
|
||||
|
|
|
@ -1195,19 +1195,23 @@ EditSession.$uid = 0;
|
|||
return isUndo ? delta.action !== "insert" : delta.action === "insert";
|
||||
}
|
||||
|
||||
var delta = deltas[0];
|
||||
var range, point;
|
||||
var lastDeltaIsInsert = false;
|
||||
if (isInsert(delta)) {
|
||||
range = Range.fromPoints(delta.start, delta.end);
|
||||
lastDeltaIsInsert = true;
|
||||
} else {
|
||||
range = Range.fromPoints(delta.start, delta.start);
|
||||
lastDeltaIsInsert = false;
|
||||
}
|
||||
var lastDeltaIsInsert;
|
||||
|
||||
for (var i = 0; i < deltas.length; i++) {
|
||||
var delta = deltas[i];
|
||||
if (!delta.start) continue; // skip folds
|
||||
if (!range) {
|
||||
if (isInsert(delta)) {
|
||||
range = Range.fromPoints(delta.start, delta.end);
|
||||
lastDeltaIsInsert = true;
|
||||
} else {
|
||||
range = Range.fromPoints(delta.start, delta.start);
|
||||
lastDeltaIsInsert = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var i = 1; i < deltas.length; i++) {
|
||||
delta = deltas[i];
|
||||
if (isInsert(delta)) {
|
||||
point = delta.start;
|
||||
if (range.compare(point.row, point.column) == -1) {
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
define(function(require, exports, module) {
|
||||
function defineProp(obj, name, val) {
|
||||
Object.defineProperty(obj, name, {
|
||||
value: val,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
||||
}
|
||||
if (!String.prototype.startsWith) {
|
||||
defineProp(String.prototype, "startsWith", function(searchString, position) {
|
||||
position = position || 0;
|
||||
return this.lastIndexOf(searchString, position) === position;
|
||||
});
|
||||
}
|
||||
if (!String.prototype.endsWith) {
|
||||
// Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
|
||||
defineProp(String.prototype, "endsWith", function(searchString, position) {
|
||||
var subjectString = this;
|
||||
if (position === undefined || position > subjectString.length) {
|
||||
position = subjectString.length;
|
||||
}
|
||||
position -= searchString.length;
|
||||
var lastIndex = subjectString.indexOf(searchString, position);
|
||||
return lastIndex !== -1 && lastIndex === position;
|
||||
});
|
||||
}
|
||||
if (!String.prototype.repeat) {
|
||||
defineProp(String.prototype, "repeat", function(count) {
|
||||
var result = "";
|
||||
var string = this;
|
||||
while (count > 0) {
|
||||
if (count & 1)
|
||||
result += string;
|
||||
|
||||
if (count >>= 1)
|
||||
string += string;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
if (!String.prototype.includes) {
|
||||
defineProp(String.prototype, "includes", function(str, position) {
|
||||
return this.indexOf(str, position != -1);
|
||||
});
|
||||
}
|
||||
if (!Object.assign) {
|
||||
Object.assign = function (target) {
|
||||
if (target === undefined || target === null) {
|
||||
throw new TypeError('Cannot convert undefined or null to object');
|
||||
}
|
||||
|
||||
var output = Object(target);
|
||||
for (var index = 1; index < arguments.length; index++) {
|
||||
var source = arguments[index];
|
||||
if (source !== undefined && source !== null) {
|
||||
Object.keys(source).forEach(function(key) {
|
||||
output[key] = source[key];
|
||||
});
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
}
|
||||
|
||||
});
|
|
@ -15,5 +15,6 @@ define(function(require, exports, module) {
|
|||
|
||||
require("./regexp");
|
||||
require("./es5-shim");
|
||||
require("./es6-shim");
|
||||
|
||||
});
|
||||
|
|
|
@ -74,7 +74,7 @@ exports.copyArray = function(array){
|
|||
var copy = [];
|
||||
for (var i=0, l=array.length; i<l; i++) {
|
||||
if (array[i] && typeof array[i] == "object")
|
||||
copy[i] = this.copyObject( array[i] );
|
||||
copy[i] = this.copyObject(array[i]);
|
||||
else
|
||||
copy[i] = array[i];
|
||||
}
|
||||
|
@ -92,14 +92,12 @@ exports.deepCopy = function deepCopy(obj) {
|
|||
}
|
||||
return copy;
|
||||
}
|
||||
var cons = obj.constructor;
|
||||
if (cons === RegExp)
|
||||
if (Object.prototype.toString.call(obj) !== "[object Object]")
|
||||
return obj;
|
||||
|
||||
copy = cons();
|
||||
for (var key in obj) {
|
||||
copy = {};
|
||||
for (var key in obj)
|
||||
copy[key] = deepCopy(obj[key]);
|
||||
}
|
||||
return copy;
|
||||
};
|
||||
|
||||
|
|
|
@ -93,3 +93,8 @@ z=<div {...this.props} x={1 + 2} y="z{a}b&" t={
|
|||
1 <a> { ++x } </a>
|
||||
</div>
|
||||
|
||||
var o = {
|
||||
t:`${[].map(x => {
|
||||
return x
|
||||
})}`
|
||||
};
|
|
@ -686,5 +686,45 @@
|
|||
],[
|
||||
"start"
|
||||
],[
|
||||
"start"
|
||||
"start",
|
||||
["storage.type","var"],
|
||||
["text"," "],
|
||||
["identifier","o"],
|
||||
["text"," "],
|
||||
["keyword.operator","="],
|
||||
["text"," "],
|
||||
["paren.lparen","{"]
|
||||
],[
|
||||
["start","no_regex","start","string.quasi.start","string.quasi.start","no_regex"],
|
||||
["text"," "],
|
||||
["identifier","t"],
|
||||
["punctuation.operator",":"],
|
||||
["string.quasi.start","`"],
|
||||
["paren.quasi.start","${"],
|
||||
["paren.lparen","["],
|
||||
["paren.rparen","]"],
|
||||
["punctuation.operator","."],
|
||||
["identifier","map"],
|
||||
["paren.lparen","("],
|
||||
["identifier","x"],
|
||||
["text"," "],
|
||||
["keyword.operator","=>"],
|
||||
["text"," "],
|
||||
["paren.lparen","{"]
|
||||
],[
|
||||
["#tmp","no_regex","start","no_regex","start","string.quasi.start","string.quasi.start","no_regex"],
|
||||
["text"," "],
|
||||
["keyword","return"],
|
||||
["text"," "],
|
||||
["identifier","x"]
|
||||
],[
|
||||
"no_regex",
|
||||
["text"," "],
|
||||
["paren.rparen","})"],
|
||||
["paren.quasi.end","}"],
|
||||
["string.quasi.end","`"]
|
||||
],[
|
||||
"start",
|
||||
["paren.rparen","}"],
|
||||
["punctuation.operator",";"]
|
||||
]]
|
|
@ -354,9 +354,8 @@ var JavaScriptHighlightRules = function(options) {
|
|||
this.next = val == "{" ? this.nextState : "";
|
||||
if (val == "{" && stack.length) {
|
||||
stack.unshift("start", state);
|
||||
return "paren";
|
||||
}
|
||||
if (val == "}" && stack.length) {
|
||||
else if (val == "}" && stack.length) {
|
||||
stack.shift();
|
||||
this.next = stack.shift();
|
||||
if (this.next.indexOf("string") != -1 || this.next.indexOf("jsx") != -1)
|
||||
|
|
|
@ -245,6 +245,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
|
||||
this.$loop.schedule(this.CHANGE_FULL);
|
||||
// this.session.$setFontMetrics(this.$fontMetrics);
|
||||
this.scrollBarV.scrollLeft = this.scrollBarV.scrollTop = null;
|
||||
|
||||
this.onChangeNewLineMode = this.onChangeNewLineMode.bind(this);
|
||||
this.onChangeNewLineMode()
|
||||
|
|
|
@ -210,6 +210,7 @@ window.onmessage = function(e) {
|
|||
else if (msg.init) {
|
||||
window.initBaseUrls(msg.tlns);
|
||||
require("ace/lib/es5-shim");
|
||||
require("ace/lib/es6-shim");
|
||||
sender = window.sender = window.initSender();
|
||||
var clazz = require(msg.module)[msg.classname];
|
||||
main = window.main = new clazz(sender);
|
||||
|
|
|
@ -15,34 +15,26 @@ module.constructor.prototype._compile = function(content, filename){
|
|||
};
|
||||
|
||||
global.define = function (id, injects, factory) {
|
||||
var DEFAULT_INJECTS = ["require", "exports", "module"];
|
||||
|
||||
// infere the module
|
||||
// infer the module
|
||||
var currentModule = moduleStack[moduleStack.length-1];
|
||||
var mod = currentModule || module.parent || require.main;
|
||||
|
||||
// parse arguments
|
||||
if (!factory) {
|
||||
// two or less arguments
|
||||
// assign arguments
|
||||
if (arguments.length === 1) {
|
||||
factory = id;
|
||||
injects = DEFAULT_INJECTS;
|
||||
id = null;
|
||||
}
|
||||
else if (arguments.length === 2) {
|
||||
factory = injects;
|
||||
if (factory) {
|
||||
// two args
|
||||
if (typeof id === "string") {
|
||||
if (id !== mod.id) {
|
||||
throw new Error("Can not assign module to a different id than the current file");
|
||||
}
|
||||
// default injects
|
||||
injects = [];
|
||||
}
|
||||
else{
|
||||
// anonymous, deps included
|
||||
injects = id;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// only one arg, just the factory
|
||||
factory = id;
|
||||
injects = [];
|
||||
}
|
||||
injects = id;
|
||||
id = null;
|
||||
}
|
||||
|
||||
if (typeof id === "string" && id !== mod.id) {
|
||||
throw new Error("Can not assign module to a different id than the current file");
|
||||
}
|
||||
|
||||
var req = function(module, relativeId, callback) {
|
||||
|
@ -68,8 +60,6 @@ global.define = function (id, injects, factory) {
|
|||
return require(fileName);
|
||||
}.bind(this, mod);
|
||||
|
||||
injects.unshift("require", "exports", "module");
|
||||
|
||||
id = mod.id;
|
||||
if (typeof factory !== "function") {
|
||||
// we can just provide a plain object
|
||||
|
|
|
@ -412,7 +412,11 @@ function loadText(path, cb) {
|
|||
var xhr = new window.XMLHttpRequest();
|
||||
xhr.open("GET", path, true);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
||||
xhr.onload = function(e) { cb(null, xhr.responseText, xhr); };
|
||||
xhr.onload = function(e) {
|
||||
if (xhr.status > 399 && xhr.status < 600)
|
||||
return cb(xhr);
|
||||
cb(null, xhr.responseText, xhr);
|
||||
};
|
||||
xhr.onabort = xhr.onerror = function(e) { cb(e); };
|
||||
xhr.send("");
|
||||
}
|
||||
|
@ -425,12 +429,9 @@ var loadScript = function(path, id, callback) {
|
|||
if (!/https?:/.test(path))
|
||||
path = host + path;
|
||||
var cb = function(e, val, deps) {
|
||||
if (e) console.error("Couldn't load module " + module, e);
|
||||
if (e) return processLoadQueue({ id: id, path: path });
|
||||
|
||||
nextModule = {
|
||||
name: id,
|
||||
deps: deps
|
||||
};
|
||||
nextModule = { name: id, deps: deps };
|
||||
window.eval(val + "\n//# sourceURL=" + path);
|
||||
callback(null, id);
|
||||
return define.loaded[id];
|
||||
|
@ -443,9 +444,15 @@ var loadCached = function(path, cb) {
|
|||
return loadText(path, cb);
|
||||
function loadNew() {
|
||||
loadText(path, function(e, val, xhr) {
|
||||
var m = cb(e, val);
|
||||
if (val) {
|
||||
try {
|
||||
var m = cb(e, val);
|
||||
} catch(err) {
|
||||
ideCache.delete(path);
|
||||
e = err;
|
||||
}
|
||||
if (!e) {
|
||||
var ETAG = xhr.getResponseHeader("ETAG");
|
||||
if (!ETAG) return;
|
||||
var res = new Response(val);
|
||||
res.headers.set("ETAG", ETAG);
|
||||
var req = new Request(path);
|
||||
|
@ -467,13 +474,16 @@ var loadCached = function(path, cb) {
|
|||
ideCache.match(path).then(function(e) {
|
||||
if (!e)
|
||||
return loadNew();
|
||||
e.text().then(function(val) {
|
||||
return e.text().then(function(val) {
|
||||
var deps = e.headers.get("deps");
|
||||
if (typeof deps == "string")
|
||||
deps = deps ? deps.split(",") : [];
|
||||
|
||||
cb(null, val, deps);
|
||||
});
|
||||
}).catch(function() {
|
||||
loadNew();
|
||||
ideCache.delete(path);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -532,7 +542,11 @@ function post(path, val, progress, cb) {
|
|||
var xhr = new window.XMLHttpRequest();
|
||||
xhr.open("POST", path, true);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
||||
xhr.onload = function(e) { cb(null, xhr.responseText, xhr); };
|
||||
xhr.onload = function(e) {
|
||||
if (xhr.status > 399 && xhr.status < 600)
|
||||
return cb(xhr);
|
||||
cb(null, xhr.responseText, xhr);
|
||||
};
|
||||
xhr.onreadystatechange = function(e) { progress(xhr.responseText, xhr); };
|
||||
xhr.onabort = xhr.onerror = function(e) { cb(e); };
|
||||
xhr.send(val);
|
||||
|
|
|
@ -277,11 +277,9 @@ else (function () {
|
|||
});
|
||||
}
|
||||
|
||||
function resolveConfig(config, base, callback) {
|
||||
if (typeof base == "function") {
|
||||
callback = base;
|
||||
base = "";
|
||||
}
|
||||
function resolveConfig(config, base, callback, errback) {
|
||||
if (typeof base == "function")
|
||||
return resolveConfig(config, "", arguments[1], arguments[2]);
|
||||
|
||||
var paths = [], pluginIndexes = {};
|
||||
config.forEach(function (plugin, index) {
|
||||
|
@ -306,7 +304,7 @@ else (function () {
|
|||
plugin.consumes = module.consumes || [];
|
||||
});
|
||||
callback(null, config);
|
||||
});
|
||||
}, errback);
|
||||
}
|
||||
}());
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
// These users don't have backups made of their workspaces and if they are supposed to be archived they are deleted instead.
|
||||
var CI_TEMP_USERS = [
|
||||
733399, // branches
|
||||
]
|
||||
|
||||
var ciHelper = {
|
||||
isTempUser: function (userId) {
|
||||
return CI_TEMP_USERS.indexOf(userId) >= 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = ciHelper;
|
|
@ -0,0 +1,46 @@
|
|||
if (define === undefined) {
|
||||
var define = function(fn) {
|
||||
fn(require, exports, module);
|
||||
};
|
||||
}
|
||||
|
||||
define(function(require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
function formatUser(user) {
|
||||
if (!user) return {}; // empty traits get ignored
|
||||
|
||||
var traits = {
|
||||
uid: user.id || user.uid,
|
||||
username: user.name || user.username,
|
||||
email: user.email,
|
||||
createdAt: user.date_add,
|
||||
active: !!user.active,
|
||||
firstName: getFirstName(user),
|
||||
lastName: getLastName(user),
|
||||
name: user.fullname || user.name,
|
||||
pricingPlan: user.premium ? "Premium" : "Free",
|
||||
region: user.region
|
||||
};
|
||||
|
||||
return traits;
|
||||
}
|
||||
|
||||
function getFirstName(user){
|
||||
if (user.firstname) return user.firstname;
|
||||
|
||||
if (!user.fullname) return undefined;
|
||||
|
||||
return user.fullname.split(' ').slice(0, 1).join(' ');
|
||||
}
|
||||
|
||||
function getLastName(user){
|
||||
if (user.lastname) return user.lastname;
|
||||
|
||||
if (!user.fullname) return undefined;
|
||||
|
||||
return user.fullname.split(' ').slice(1).join(' ');
|
||||
}
|
||||
|
||||
module.exports = formatUser;
|
||||
});
|
|
@ -5,11 +5,36 @@ define(function(require, exports, module) {
|
|||
|
||||
var providers = {
|
||||
"bitbucket.org": "bitbucket",
|
||||
"github.com": "github"
|
||||
"github.com": "github",
|
||||
"source.developers.google.com": "google",
|
||||
};
|
||||
var defaultProvider = "unknown";
|
||||
|
||||
|
||||
/**
|
||||
* Checks if there are unexpected (dangerous) characters in the url
|
||||
*
|
||||
* Source:
|
||||
*
|
||||
* http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
|
||||
*
|
||||
* The application shall quote the following characters if they are to represent themselves:
|
||||
*
|
||||
* | & ; < > ( ) $ ` \ " ' <space> <tab> <newline>
|
||||
*
|
||||
* and the following may need to be quoted under certain circumstances. That is, these characters may be special depending on conditions described elsewhere in this volume of IEEE Std 1003.1-2001:
|
||||
*
|
||||
* * ? [ # ˜ = %
|
||||
*/
|
||||
function containsDangerousShellCharacters(url){
|
||||
return /[\s;&|><*?`$(){}[\]!#]/.test(url);
|
||||
}
|
||||
|
||||
module.exports = function(url) {
|
||||
// scm urls cannot contain any of these
|
||||
if (containsDangerousShellCharacters(url))
|
||||
return;
|
||||
|
||||
var m = url.match(/^(git)@([\w\.\d\-\_]+)(?:\/|:)([\w\.\d\-\_\/]+)/);
|
||||
if (m) {
|
||||
return {
|
||||
|
@ -38,12 +63,19 @@ define(function(require, exports, module) {
|
|||
case "github":
|
||||
scm = "git";
|
||||
break;
|
||||
case "google":
|
||||
scm = "git";
|
||||
break;
|
||||
case "bitbucket":
|
||||
scm = parsed.pathname.match(/\.git$/) ? "git": "hg";
|
||||
break;
|
||||
default:
|
||||
scm = parsed.pathname.match(/\.git$/) ? "git": "hg";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return {
|
||||
protocol: parsed.protocol,
|
||||
scm: scm,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/*global describe it before after beforeEach afterEach */
|
||||
"use strict";
|
||||
|
||||
|
@ -11,50 +12,50 @@ require("amd-loader");
|
|||
var assert = require("assert");
|
||||
var parse = require("./scm_url_parse");
|
||||
|
||||
describe(__filename, function(){
|
||||
describe(__filename, function() {
|
||||
|
||||
describe("#parse", function() {
|
||||
it("should parse ssh url", function(done) {
|
||||
var url = parse("git@github.com:fjakobs/lispjs.git");
|
||||
assert.equal(url.scm, "git");
|
||||
assert.equal(url.protocol, "ssh:");
|
||||
assert.equal(url.auth, "git");
|
||||
assert.equal(url.hostname, "github.com");
|
||||
assert.equal(url.pathname, "fjakobs/lispjs.git");
|
||||
done();
|
||||
var url = parse("git@github.com:fjakobs/lispjs.git");
|
||||
assert.equal(url.scm, "git");
|
||||
assert.equal(url.protocol, "ssh:");
|
||||
assert.equal(url.auth, "git");
|
||||
assert.equal(url.hostname, "github.com");
|
||||
assert.equal(url.pathname, "fjakobs/lispjs.git");
|
||||
done();
|
||||
|
||||
}),
|
||||
}),
|
||||
|
||||
it("should parse git url", function(done) {
|
||||
var url = parse("git://github.com/fjakobs/lispjs.git");
|
||||
assert.equal(url.scm, "git");
|
||||
assert.equal(url.protocol, "git:");
|
||||
assert.equal(url.hostname, "github.com");
|
||||
assert.equal(url.pathname, "fjakobs/lispjs.git");
|
||||
done();
|
||||
it("should parse git url", function(done) {
|
||||
var url = parse("git://github.com/fjakobs/lispjs.git");
|
||||
assert.equal(url.scm, "git");
|
||||
assert.equal(url.protocol, "git:");
|
||||
assert.equal(url.hostname, "github.com");
|
||||
assert.equal(url.pathname, "fjakobs/lispjs.git");
|
||||
done();
|
||||
|
||||
}),
|
||||
}),
|
||||
|
||||
it("should parse https url", function(done) {
|
||||
var url = parse("https://fjakobs@github.com/fjakobs/lispjs.git");
|
||||
assert.equal(url.protocol, "https:");
|
||||
assert.equal(url.scm, "git");
|
||||
assert.equal(url.auth, "fjakobs");
|
||||
assert.equal(url.hostname, "github.com");
|
||||
assert.equal(url.pathname, "fjakobs/lispjs.git");
|
||||
done();
|
||||
it("should parse https url", function(done) {
|
||||
var url = parse("https://fjakobs@github.com/fjakobs/lispjs.git");
|
||||
assert.equal(url.protocol, "https:");
|
||||
assert.equal(url.scm, "git");
|
||||
assert.equal(url.auth, "fjakobs");
|
||||
assert.equal(url.hostname, "github.com");
|
||||
assert.equal(url.pathname, "fjakobs/lispjs.git");
|
||||
done();
|
||||
|
||||
}),
|
||||
}),
|
||||
|
||||
it("should parse Bitbucket url", function(done) {
|
||||
var url = parse("git@bitbucket.org/Richard/expressling.git");
|
||||
assert.equal(url.protocol, "ssh:");
|
||||
assert.equal(url.scm, "git");
|
||||
assert.equal(url.auth, "git");
|
||||
assert.equal(url.hostname, "bitbucket.org");
|
||||
assert.equal(url.pathname, "Richard/expressling.git");
|
||||
done();
|
||||
});
|
||||
it("should parse Bitbucket url", function(done) {
|
||||
var url = parse("git@bitbucket.org/Richard/expressling.git");
|
||||
assert.equal(url.protocol, "ssh:");
|
||||
assert.equal(url.scm, "git");
|
||||
assert.equal(url.auth, "git");
|
||||
assert.equal(url.hostname, "bitbucket.org");
|
||||
assert.equal(url.pathname, "Richard/expressling.git");
|
||||
done();
|
||||
});
|
||||
|
||||
it("should parse Bitbucket hg ssh url", function(done) {
|
||||
var url = parse("ssh://hg@bitbucket.org/fjakobs/juhu");
|
||||
|
@ -74,6 +75,30 @@ describe(__filename, function(){
|
|||
assert.equal(url.pathname, "arunoda/meteor-streams");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("Should refuse a git url with dangerous shell chars in it", function() {
|
||||
var validUrls = [
|
||||
"https://github.com/arunoda/meteor-streams",
|
||||
"https://fjakobs@github.com/fjakobs/lispjs.git",
|
||||
"ssh://hg@bitbucket.org/fjakobs/juhu",
|
||||
"git@bitbucket.org/Richard/expressling.git",
|
||||
"git://github.com/fjakobs/lispjs.git",
|
||||
"git@github.com:fjakobs/lispjs.git",
|
||||
];
|
||||
|
||||
var exploits = [
|
||||
"&:(){ :|:& };:",
|
||||
"&rm -rf /",
|
||||
";uname-a"
|
||||
];
|
||||
|
||||
validUrls.forEach(function(url) {
|
||||
assert.ok(parse(url), "This url is normally valid: " + url);
|
||||
|
||||
exploits.forEach(function(exploit) {
|
||||
assert.equal(parse(url + exploit), undefined, "But not with an exploit: " + url + exploit);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -89,7 +89,7 @@ function getBaseUrl(req, sourceBaseUrlPattern, targetBaseUrlPattern) {
|
|||
targetHost = hostMatch[1];
|
||||
}
|
||||
else {
|
||||
console.error(new Error("Could not construct URL: request host " + sourceHost + " should match " + sourceBaseUrlPattern));
|
||||
console.trace("Warning: could not construct URL: request host " + sourceHost + " should match " + sourceBaseUrlPattern + "; falling back to c9.io");
|
||||
|
||||
targetHost = "c9.io";
|
||||
}
|
||||
|
|
|
@ -25,10 +25,6 @@ var _tokentype = _dereq_("./tokentype");
|
|||
|
||||
var _state = _dereq_("./state");
|
||||
|
||||
var _identifier = _dereq_("./identifier");
|
||||
|
||||
var _util = _dereq_("./util");
|
||||
|
||||
var pp = _state.Parser.prototype;
|
||||
|
||||
// Check if property name clashes with already added.
|
||||
|
@ -38,8 +34,7 @@ var pp = _state.Parser.prototype;
|
|||
|
||||
pp.checkPropClash = function (prop, propHash) {
|
||||
if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) return;
|
||||
var key = prop.key,
|
||||
name = undefined;
|
||||
var key = prop.key;var name = undefined;
|
||||
switch (key.type) {
|
||||
case "Identifier":
|
||||
name = key.name;break;
|
||||
|
@ -49,6 +44,7 @@ pp.checkPropClash = function (prop, propHash) {
|
|||
return;
|
||||
}
|
||||
var kind = prop.kind;
|
||||
|
||||
if (this.options.ecmaVersion >= 6) {
|
||||
if (name === "__proto__" && kind === "init") {
|
||||
if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property");
|
||||
|
@ -56,9 +52,9 @@ pp.checkPropClash = function (prop, propHash) {
|
|||
}
|
||||
return;
|
||||
}
|
||||
var other = undefined;
|
||||
if (_util.has(propHash, name)) {
|
||||
other = propHash[name];
|
||||
name = "$" + name;
|
||||
var other = propHash[name];
|
||||
if (other) {
|
||||
var isGetSet = kind !== "init";
|
||||
if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) this.raise(key.start, "Redefinition of property");
|
||||
} else {
|
||||
|
@ -86,14 +82,14 @@ pp.checkPropClash = function (prop, propHash) {
|
|||
// and object pattern might appear (so it's possible to raise
|
||||
// delayed syntax error at correct position).
|
||||
|
||||
pp.parseExpression = function (noIn, refShorthandDefaultPos) {
|
||||
pp.parseExpression = function (noIn, refDestructuringErrors) {
|
||||
var startPos = this.start,
|
||||
startLoc = this.startLoc;
|
||||
var expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos);
|
||||
var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);
|
||||
if (this.type === _tokentype.types.comma) {
|
||||
var node = this.startNodeAt(startPos, startLoc);
|
||||
node.expressions = [expr];
|
||||
while (this.eat(_tokentype.types.comma)) node.expressions.push(this.parseMaybeAssign(noIn, refShorthandDefaultPos));
|
||||
while (this.eat(_tokentype.types.comma)) node.expressions.push(this.parseMaybeAssign(noIn, refDestructuringErrors));
|
||||
return this.finishNode(node, "SequenceExpression");
|
||||
}
|
||||
return expr;
|
||||
|
@ -102,43 +98,42 @@ pp.parseExpression = function (noIn, refShorthandDefaultPos) {
|
|||
// Parse an assignment expression. This includes applications of
|
||||
// operators like `+=`.
|
||||
|
||||
pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) {
|
||||
pp.parseMaybeAssign = function (noIn, refDestructuringErrors, afterLeftParse) {
|
||||
if (this.type == _tokentype.types._yield && this.inGenerator) return this.parseYield();
|
||||
|
||||
var failOnShorthandAssign = undefined;
|
||||
if (!refShorthandDefaultPos) {
|
||||
refShorthandDefaultPos = { start: 0 };
|
||||
failOnShorthandAssign = true;
|
||||
} else {
|
||||
failOnShorthandAssign = false;
|
||||
var validateDestructuring = false;
|
||||
if (!refDestructuringErrors) {
|
||||
refDestructuringErrors = { shorthandAssign: 0, trailingComma: 0 };
|
||||
validateDestructuring = true;
|
||||
}
|
||||
var startPos = this.start,
|
||||
startLoc = this.startLoc;
|
||||
if (this.type == _tokentype.types.parenL || this.type == _tokentype.types.name) this.potentialArrowAt = this.start;
|
||||
var left = this.parseMaybeConditional(noIn, refShorthandDefaultPos);
|
||||
var left = this.parseMaybeConditional(noIn, refDestructuringErrors);
|
||||
if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc);
|
||||
if (this.type.isAssign) {
|
||||
if (validateDestructuring) this.checkPatternErrors(refDestructuringErrors, true);
|
||||
var node = this.startNodeAt(startPos, startLoc);
|
||||
node.operator = this.value;
|
||||
node.left = this.type === _tokentype.types.eq ? this.toAssignable(left) : left;
|
||||
refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly
|
||||
refDestructuringErrors.shorthandAssign = 0; // reset because shorthand default was used correctly
|
||||
this.checkLVal(left);
|
||||
this.next();
|
||||
node.right = this.parseMaybeAssign(noIn);
|
||||
return this.finishNode(node, "AssignmentExpression");
|
||||
} else if (failOnShorthandAssign && refShorthandDefaultPos.start) {
|
||||
this.unexpected(refShorthandDefaultPos.start);
|
||||
} else {
|
||||
if (validateDestructuring) this.checkExpressionErrors(refDestructuringErrors, true);
|
||||
}
|
||||
return left;
|
||||
};
|
||||
|
||||
// Parse a ternary conditional (`?:`) operator.
|
||||
|
||||
pp.parseMaybeConditional = function (noIn, refShorthandDefaultPos) {
|
||||
pp.parseMaybeConditional = function (noIn, refDestructuringErrors) {
|
||||
var startPos = this.start,
|
||||
startLoc = this.startLoc;
|
||||
var expr = this.parseExprOps(noIn, refShorthandDefaultPos);
|
||||
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
|
||||
var expr = this.parseExprOps(noIn, refDestructuringErrors);
|
||||
if (this.checkExpressionErrors(refDestructuringErrors)) return expr;
|
||||
if (this.eat(_tokentype.types.question)) {
|
||||
var node = this.startNodeAt(startPos, startLoc);
|
||||
node.test = expr;
|
||||
|
@ -152,11 +147,11 @@ pp.parseMaybeConditional = function (noIn, refShorthandDefaultPos) {
|
|||
|
||||
// Start the precedence parser.
|
||||
|
||||
pp.parseExprOps = function (noIn, refShorthandDefaultPos) {
|
||||
pp.parseExprOps = function (noIn, refDestructuringErrors) {
|
||||
var startPos = this.start,
|
||||
startLoc = this.startLoc;
|
||||
var expr = this.parseMaybeUnary(refShorthandDefaultPos);
|
||||
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
|
||||
var expr = this.parseMaybeUnary(refDestructuringErrors);
|
||||
if (this.checkExpressionErrors(refDestructuringErrors)) return expr;
|
||||
return this.parseExprOp(expr, startPos, startLoc, -1, noIn);
|
||||
};
|
||||
|
||||
|
@ -187,7 +182,7 @@ pp.parseExprOp = function (left, leftStartPos, leftStartLoc, minPrec, noIn) {
|
|||
|
||||
// Parse unary operators, both prefix and postfix.
|
||||
|
||||
pp.parseMaybeUnary = function (refShorthandDefaultPos) {
|
||||
pp.parseMaybeUnary = function (refDestructuringErrors) {
|
||||
if (this.type.prefix) {
|
||||
var node = this.startNode(),
|
||||
update = this.type === _tokentype.types.incDec;
|
||||
|
@ -195,14 +190,14 @@ pp.parseMaybeUnary = function (refShorthandDefaultPos) {
|
|||
node.prefix = true;
|
||||
this.next();
|
||||
node.argument = this.parseMaybeUnary();
|
||||
if (refShorthandDefaultPos && refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
|
||||
this.checkExpressionErrors(refDestructuringErrors, true);
|
||||
if (update) this.checkLVal(node.argument);else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") this.raise(node.start, "Deleting local variable in strict mode");
|
||||
return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
|
||||
}
|
||||
var startPos = this.start,
|
||||
startLoc = this.startLoc;
|
||||
var expr = this.parseExprSubscripts(refShorthandDefaultPos);
|
||||
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
|
||||
var expr = this.parseExprSubscripts(refDestructuringErrors);
|
||||
if (this.checkExpressionErrors(refDestructuringErrors)) return expr;
|
||||
while (this.type.postfix && !this.canInsertSemicolon()) {
|
||||
var node = this.startNodeAt(startPos, startLoc);
|
||||
node.operator = this.value;
|
||||
|
@ -217,11 +212,12 @@ pp.parseMaybeUnary = function (refShorthandDefaultPos) {
|
|||
|
||||
// Parse call, dot, and `[]`-subscript expressions.
|
||||
|
||||
pp.parseExprSubscripts = function (refShorthandDefaultPos) {
|
||||
pp.parseExprSubscripts = function (refDestructuringErrors) {
|
||||
var startPos = this.start,
|
||||
startLoc = this.startLoc;
|
||||
var expr = this.parseExprAtom(refShorthandDefaultPos);
|
||||
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
|
||||
var expr = this.parseExprAtom(refDestructuringErrors);
|
||||
var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")";
|
||||
if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) return expr;
|
||||
return this.parseSubscripts(expr, startPos, startLoc);
|
||||
};
|
||||
|
||||
|
@ -261,7 +257,7 @@ pp.parseSubscripts = function (base, startPos, startLoc, noCalls) {
|
|||
// `new`, or an expression wrapped in punctuation like `()`, `[]`,
|
||||
// or `{}`.
|
||||
|
||||
pp.parseExprAtom = function (refShorthandDefaultPos) {
|
||||
pp.parseExprAtom = function (refDestructuringErrors) {
|
||||
var node = undefined,
|
||||
canBeArrow = this.potentialArrowAt == this.start;
|
||||
switch (this.type) {
|
||||
|
@ -277,6 +273,18 @@ pp.parseExprAtom = function (refShorthandDefaultPos) {
|
|||
if (this.inGenerator) this.unexpected();
|
||||
|
||||
case _tokentype.types.name:
|
||||
// quick hack to allow async and await
|
||||
if (this.value == "async" && /^[ \t]+function\b/.test(this.input.slice(this.end))) {
|
||||
node = this.startNode();
|
||||
this.next();
|
||||
return this.parseExprAtom(refDestructuringErrors);
|
||||
}
|
||||
if (this.value == "await" && /^[ \t]+[\w\x1f-\uffff]/.test(this.input.slice(this.end))) {
|
||||
node = this.startNode();
|
||||
this.next();
|
||||
return this.parseExprAtom(refDestructuringErrors);
|
||||
}
|
||||
|
||||
var startPos = this.start,
|
||||
startLoc = this.startLoc;
|
||||
var id = this.parseIdent(this.type !== _tokentype.types.name);
|
||||
|
@ -309,11 +317,11 @@ pp.parseExprAtom = function (refShorthandDefaultPos) {
|
|||
if (this.options.ecmaVersion >= 7 && this.type === _tokentype.types._for) {
|
||||
return this.parseComprehension(node, false);
|
||||
}
|
||||
node.elements = this.parseExprList(_tokentype.types.bracketR, true, true, refShorthandDefaultPos);
|
||||
node.elements = this.parseExprList(_tokentype.types.bracketR, true, true, refDestructuringErrors);
|
||||
return this.finishNode(node, "ArrayExpression");
|
||||
|
||||
case _tokentype.types.braceL:
|
||||
return this.parseObj(false, refShorthandDefaultPos);
|
||||
return this.parseObj(false, refDestructuringErrors);
|
||||
|
||||
case _tokentype.types._function:
|
||||
node = this.startNode();
|
||||
|
@ -364,7 +372,7 @@ pp.parseParenAndDistinguishExpression = function (canBeArrow) {
|
|||
innerStartLoc = this.startLoc;
|
||||
var exprList = [],
|
||||
first = true;
|
||||
var refShorthandDefaultPos = { start: 0 },
|
||||
var refDestructuringErrors = { shorthandAssign: 0, trailingComma: 0 },
|
||||
spreadStart = undefined,
|
||||
innerParenStart = undefined;
|
||||
while (this.type !== _tokentype.types.parenR) {
|
||||
|
@ -377,7 +385,7 @@ pp.parseParenAndDistinguishExpression = function (canBeArrow) {
|
|||
if (this.type === _tokentype.types.parenL && !innerParenStart) {
|
||||
innerParenStart = this.start;
|
||||
}
|
||||
exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem));
|
||||
exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem));
|
||||
}
|
||||
}
|
||||
var innerEndPos = this.start,
|
||||
|
@ -385,13 +393,14 @@ pp.parseParenAndDistinguishExpression = function (canBeArrow) {
|
|||
this.expect(_tokentype.types.parenR);
|
||||
|
||||
if (canBeArrow && !this.canInsertSemicolon() && this.eat(_tokentype.types.arrow)) {
|
||||
this.checkPatternErrors(refDestructuringErrors, true);
|
||||
if (innerParenStart) this.unexpected(innerParenStart);
|
||||
return this.parseParenArrowList(startPos, startLoc, exprList);
|
||||
}
|
||||
|
||||
if (!exprList.length) this.unexpected(this.lastTokStart);
|
||||
if (spreadStart) this.unexpected(spreadStart);
|
||||
if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
|
||||
this.checkExpressionErrors(refDestructuringErrors, true);
|
||||
|
||||
if (exprList.length > 1) {
|
||||
val = this.startNodeAt(innerStartPos, innerStartLoc);
|
||||
|
@ -421,9 +430,11 @@ pp.parseParenArrowList = function (startPos, startLoc, exprList) {
|
|||
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList);
|
||||
};
|
||||
|
||||
// New's precedence is slightly tricky. It must allow its argument
|
||||
// to be a `[]` or dot subscript expression, but not a call — at
|
||||
// least, not without wrapping it in parentheses. Thus, it uses the
|
||||
// New's precedence is slightly tricky. It must allow its argument to
|
||||
// be a `[]` or dot subscript expression, but not a call — at least,
|
||||
// not without wrapping it in parentheses. Thus, it uses the noCalls
|
||||
// argument to parseSubscripts to prevent it from consuming the
|
||||
// argument list.
|
||||
|
||||
var empty = [];
|
||||
|
||||
|
@ -434,6 +445,7 @@ pp.parseNew = function () {
|
|||
node.meta = meta;
|
||||
node.property = this.parseIdent(true);
|
||||
if (node.property.name !== "target") this.raise(node.property.start, "The only valid meta property for new is new.target");
|
||||
if (!this.inFunction) this.raise(node.start, "new.target can only be used in functions");
|
||||
return this.finishNode(node, "MetaProperty");
|
||||
}
|
||||
var startPos = this.start,
|
||||
|
@ -474,7 +486,7 @@ pp.parseTemplate = function () {
|
|||
|
||||
// Parse an object literal or binding pattern.
|
||||
|
||||
pp.parseObj = function (isPattern, refShorthandDefaultPos) {
|
||||
pp.parseObj = function (isPattern, refDestructuringErrors) {
|
||||
var node = this.startNode(),
|
||||
first = true,
|
||||
propHash = {};
|
||||
|
@ -493,23 +505,23 @@ pp.parseObj = function (isPattern, refShorthandDefaultPos) {
|
|||
if (this.options.ecmaVersion >= 6) {
|
||||
prop.method = false;
|
||||
prop.shorthand = false;
|
||||
if (isPattern || refShorthandDefaultPos) {
|
||||
if (isPattern || refDestructuringErrors) {
|
||||
startPos = this.start;
|
||||
startLoc = this.startLoc;
|
||||
}
|
||||
if (!isPattern) isGenerator = this.eat(_tokentype.types.star);
|
||||
}
|
||||
this.parsePropertyName(prop);
|
||||
this.parsePropertyValue(prop, isPattern, isGenerator, startPos, startLoc, refShorthandDefaultPos);
|
||||
this.parsePropertyValue(prop, isPattern, isGenerator, startPos, startLoc, refDestructuringErrors);
|
||||
this.checkPropClash(prop, propHash);
|
||||
node.properties.push(this.finishNode(prop, "Property"));
|
||||
}
|
||||
return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression");
|
||||
};
|
||||
|
||||
pp.parsePropertyValue = function (prop, isPattern, isGenerator, startPos, startLoc, refShorthandDefaultPos) {
|
||||
pp.parsePropertyValue = function (prop, isPattern, isGenerator, startPos, startLoc, refDestructuringErrors) {
|
||||
if (this.eat(_tokentype.types.colon)) {
|
||||
prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos);
|
||||
prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
|
||||
prop.kind = "init";
|
||||
} else if (this.options.ecmaVersion >= 6 && this.type === _tokentype.types.parenL) {
|
||||
if (isPattern) this.unexpected();
|
||||
|
@ -526,13 +538,14 @@ pp.parsePropertyValue = function (prop, isPattern, isGenerator, startPos, startL
|
|||
var start = prop.value.start;
|
||||
if (prop.kind === "get") this.raise(start, "getter should have no params");else this.raise(start, "setter should have exactly one param");
|
||||
}
|
||||
if (prop.kind === "set" && prop.value.params[0].type === "RestElement") this.raise(prop.value.params[0].start, "Setter cannot use rest params");
|
||||
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
|
||||
prop.kind = "init";
|
||||
if (isPattern) {
|
||||
if (this.isKeyword(prop.key.name) || this.strict && (_identifier.reservedWords.strictBind(prop.key.name) || _identifier.reservedWords.strict(prop.key.name)) || !this.options.allowReserved && this.isReservedWord(prop.key.name)) this.raise(prop.key.start, "Binding " + prop.key.name);
|
||||
if (this.keywords.test(prop.key.name) || (this.strict ? this.reservedWordsStrictBind : this.reservedWords).test(prop.key.name)) this.raise(prop.key.start, "Binding " + prop.key.name);
|
||||
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
|
||||
} else if (this.type === _tokentype.types.eq && refShorthandDefaultPos) {
|
||||
if (!refShorthandDefaultPos.start) refShorthandDefaultPos.start = this.start;
|
||||
} else if (this.type === _tokentype.types.eq && refDestructuringErrors) {
|
||||
if (!refDestructuringErrors.shorthandAssign) refDestructuringErrors.shorthandAssign = this.start;
|
||||
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
|
||||
} else {
|
||||
prop.value = prop.key;
|
||||
|
@ -572,10 +585,7 @@ pp.parseMethod = function (isGenerator) {
|
|||
this.initFunction(node);
|
||||
this.expect(_tokentype.types.parenL);
|
||||
node.params = this.parseBindingList(_tokentype.types.parenR, false, false);
|
||||
var allowExpressionBody = undefined;
|
||||
if (this.options.ecmaVersion >= 6) {
|
||||
node.generator = isGenerator;
|
||||
}
|
||||
if (this.options.ecmaVersion >= 6) node.generator = isGenerator;
|
||||
this.parseFunctionBody(node, false);
|
||||
return this.finishNode(node, "FunctionExpression");
|
||||
};
|
||||
|
@ -591,8 +601,8 @@ pp.parseArrowExpression = function (node, params) {
|
|||
|
||||
// Parse function body and check parameters.
|
||||
|
||||
pp.parseFunctionBody = function (node, allowExpression) {
|
||||
var isExpression = allowExpression && this.type !== _tokentype.types.braceL;
|
||||
pp.parseFunctionBody = function (node, isArrowFunction) {
|
||||
var isExpression = isArrowFunction && this.type !== _tokentype.types.braceL;
|
||||
|
||||
if (isExpression) {
|
||||
node.body = this.parseMaybeAssign();
|
||||
|
@ -613,13 +623,23 @@ pp.parseFunctionBody = function (node, allowExpression) {
|
|||
// are not repeated, and it does not try to bind the words `eval`
|
||||
// or `arguments`.
|
||||
if (this.strict || !isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) {
|
||||
var nameHash = {},
|
||||
oldStrict = this.strict;
|
||||
var oldStrict = this.strict;
|
||||
this.strict = true;
|
||||
if (node.id) this.checkLVal(node.id, true);
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
this.checkLVal(node.params[i], true, nameHash);
|
||||
}this.strict = oldStrict;
|
||||
this.checkParams(node);
|
||||
this.strict = oldStrict;
|
||||
} else if (isArrowFunction) {
|
||||
this.checkParams(node);
|
||||
}
|
||||
};
|
||||
|
||||
// Checks function params for various disallowed patterns such as using "eval"
|
||||
// or "arguments" and duplicate parameters.
|
||||
|
||||
pp.checkParams = function (node) {
|
||||
var nameHash = {};
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
this.checkLVal(node.params[i], true, nameHash);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -629,17 +649,20 @@ pp.parseFunctionBody = function (node, allowExpression) {
|
|||
// nothing in between them to be parsed as `null` (which is needed
|
||||
// for array literals).
|
||||
|
||||
pp.parseExprList = function (close, allowTrailingComma, allowEmpty, refShorthandDefaultPos) {
|
||||
pp.parseExprList = function (close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
|
||||
var elts = [],
|
||||
first = true;
|
||||
while (!this.eat(close)) {
|
||||
if (!first) {
|
||||
this.expect(_tokentype.types.comma);
|
||||
if (this.type === close && refDestructuringErrors && !refDestructuringErrors.trailingComma) {
|
||||
refDestructuringErrors.trailingComma = this.lastTokStart;
|
||||
}
|
||||
if (allowTrailingComma && this.afterTrailingComma(close)) break;
|
||||
} else first = false;
|
||||
|
||||
var elt = undefined;
|
||||
if (allowEmpty && this.type === _tokentype.types.comma) elt = null;else if (this.type === _tokentype.types.ellipsis) elt = this.parseSpread(refShorthandDefaultPos);else elt = this.parseMaybeAssign(false, refShorthandDefaultPos);
|
||||
if (allowEmpty && this.type === _tokentype.types.comma) elt = null;else if (this.type === _tokentype.types.ellipsis) elt = this.parseSpread(refDestructuringErrors);else elt = this.parseMaybeAssign(false, refDestructuringErrors);
|
||||
elts.push(elt);
|
||||
}
|
||||
return elts;
|
||||
|
@ -653,7 +676,7 @@ pp.parseIdent = function (liberal) {
|
|||
var node = this.startNode();
|
||||
if (liberal && this.options.allowReserved == "never") liberal = false;
|
||||
if (this.type === _tokentype.types.name) {
|
||||
if (!liberal && (!this.options.allowReserved && this.isReservedWord(this.value) || this.strict && _identifier.reservedWords.strict(this.value) && (this.options.ecmaVersion >= 6 || this.input.slice(this.start, this.end).indexOf("\\") == -1))) this.raise(this.start, "The keyword '" + this.value + "' is reserved");
|
||||
if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) && (this.options.ecmaVersion >= 6 || this.input.slice(this.start, this.end).indexOf("\\") == -1)) this.raise(this.start, "The keyword '" + this.value + "' is reserved");
|
||||
node.name = this.value;
|
||||
} else if (liberal && this.type.keyword) {
|
||||
node.name = this.type.keyword;
|
||||
|
@ -701,7 +724,7 @@ pp.parseComprehension = function (node, isGenerator) {
|
|||
return this.finishNode(node, "ComprehensionExpression");
|
||||
};
|
||||
|
||||
},{"./identifier":"/src\\identifier.js","./state":"/src\\state.js","./tokentype":"/src\\tokentype.js","./util":"/src\\util.js"}],"/src\\identifier.js":[function(_dereq_,module,exports){
|
||||
},{"./state":"/src\\state.js","./tokentype":"/src\\tokentype.js"}],"/src\\identifier.js":[function(_dereq_,module,exports){
|
||||
// This is a trick taken from Esprima. It turns out that, on
|
||||
// non-Chrome browsers, to check whether a string is in a set, a
|
||||
// predicate containing a big ugly `switch` statement is faster than
|
||||
|
@ -711,36 +734,19 @@ pp.parseComprehension = function (node, isGenerator) {
|
|||
//
|
||||
// It starts by sorting the words by length.
|
||||
|
||||
// Reserved word lists for various dialects of the language
|
||||
|
||||
"use strict";
|
||||
|
||||
exports.__esModule = true;
|
||||
exports.isIdentifierStart = isIdentifierStart;
|
||||
exports.isIdentifierChar = isIdentifierChar;
|
||||
// Removed to create an eval-free library
|
||||
|
||||
// Reserved word lists for various dialects of the language
|
||||
|
||||
var reservedWords = {
|
||||
3: function anonymous(str
|
||||
/**/) {
|
||||
switch(str.length){case 6:switch(str){case "double":case "export":case "import":case "native":case "public":case "static":case "throws":return true}return false;case 4:switch(str){case "byte":case "char":case "enum":case "goto":case "long":return true}return false;case 5:switch(str){case "class":case "final":case "float":case "short":case "super":return true}return false;case 7:switch(str){case "boolean":case "extends":case "package":case "private":return true}return false;case 9:switch(str){case "interface":case "protected":case "transient":return true}return false;case 8:switch(str){case "abstract":case "volatile":return true}return false;case 10:return str === "implements";case 3:return str === "int";case 12:return str === "synchronized";}
|
||||
},
|
||||
5: function anonymous(str
|
||||
/**/) {
|
||||
switch(str.length){case 5:switch(str){case "class":case "super":case "const":return true}return false;case 6:switch(str){case "export":case "import":return true}return false;case 4:return str === "enum";case 7:return str === "extends";}
|
||||
},
|
||||
6: function anonymous(str
|
||||
/**/) {
|
||||
switch(str){case "enum":case "await":return true}return false;
|
||||
},
|
||||
strict: function anonymous(str
|
||||
/**/) {
|
||||
switch(str.length){case 9:switch(str){case "interface":case "protected":return true}return false;case 7:switch(str){case "package":case "private":return true}return false;case 6:switch(str){case "public":case "static":return true}return false;case 10:return str === "implements";case 3:return str === "let";case 5:return str === "yield";}
|
||||
},
|
||||
strictBind: function anonymous(str
|
||||
/**/) {
|
||||
switch(str){case "eval":case "arguments":return true}return false;
|
||||
}
|
||||
3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",
|
||||
5: "class enum extends super const export import",
|
||||
6: "enum",
|
||||
strict: "implements interface let package private protected public static yield",
|
||||
strictBind: "eval arguments"
|
||||
};
|
||||
|
||||
exports.reservedWords = reservedWords;
|
||||
|
@ -749,14 +755,8 @@ exports.reservedWords = reservedWords;
|
|||
var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
|
||||
|
||||
var keywords = {
|
||||
5: function anonymous(str
|
||||
/**/) {
|
||||
switch(str.length){case 4:switch(str){case "case":case "else":case "with":case "null":case "true":case "void":case "this":return true}return false;case 5:switch(str){case "break":case "catch":case "throw":case "while":case "false":return true}return false;case 3:switch(str){case "for":case "try":case "var":case "new":return true}return false;case 6:switch(str){case "return":case "switch":case "typeof":case "delete":return true}return false;case 8:switch(str){case "continue":case "debugger":case "function":return true}return false;case 2:switch(str){case "do":case "if":case "in":return true}return false;case 7:switch(str){case "default":case "finally":return true}return false;case 10:return str === "instanceof";}
|
||||
},
|
||||
6: function anonymous(str
|
||||
/**/) {
|
||||
switch(str.length){case 5:switch(str){case "break":case "catch":case "throw":case "while":case "false":case "const":case "class":case "yield":case "super":return true}return false;case 4:switch(str){case "case":case "else":case "with":case "null":case "true":case "void":case "this":return true}return false;case 6:switch(str){case "return":case "switch":case "typeof":case "delete":case "export":case "import":return true}return false;case 3:switch(str){case "for":case "try":case "var":case "new":case "let":return true}return false;case 8:switch(str){case "continue":case "debugger":case "function":return true}return false;case 7:switch(str){case "default":case "finally":case "extends":return true}return false;case 2:switch(str){case "do":case "if":case "in":return true}return false;case 10:return str === "instanceof";}
|
||||
}
|
||||
5: ecma5AndLessKeywords,
|
||||
6: ecma5AndLessKeywords + " let const class extends export import yield super"
|
||||
};
|
||||
|
||||
exports.keywords = keywords;
|
||||
|
@ -793,11 +793,11 @@ function isIdentifierChar(code, astral) {
|
|||
// Git repositories for Acorn are available at
|
||||
//
|
||||
// http://marijnhaverbeke.nl/git/acorn
|
||||
// https://github.com/marijnh/acorn.git
|
||||
// https://github.com/ternjs/acorn.git
|
||||
//
|
||||
// Please use the [github bug tracker][ghbt] to report issues.
|
||||
//
|
||||
// [ghbt]: https://github.com/marijnh/acorn/issues
|
||||
// [ghbt]: https://github.com/ternjs/acorn/issues
|
||||
//
|
||||
// This file defines the main parser interface. The library also comes
|
||||
// with a [error-tolerant parser][dammit] and an
|
||||
|
@ -815,8 +815,6 @@ exports.tokenizer = tokenizer;
|
|||
|
||||
var _state = _dereq_("./state");
|
||||
|
||||
var _options = _dereq_("./options");
|
||||
|
||||
_dereq_("./parseutil");
|
||||
|
||||
_dereq_("./statement");
|
||||
|
@ -829,6 +827,9 @@ _dereq_("./location");
|
|||
|
||||
exports.Parser = _state.Parser;
|
||||
exports.plugins = _state.plugins;
|
||||
|
||||
var _options = _dereq_("./options");
|
||||
|
||||
exports.defaultOptions = _options.defaultOptions;
|
||||
|
||||
var _locutil = _dereq_("./locutil");
|
||||
|
@ -865,7 +866,7 @@ var _whitespace = _dereq_("./whitespace");
|
|||
exports.isNewLine = _whitespace.isNewLine;
|
||||
exports.lineBreak = _whitespace.lineBreak;
|
||||
exports.lineBreakG = _whitespace.lineBreakG;
|
||||
var version = "2.1.1";
|
||||
var version = "2.7.0";
|
||||
|
||||
exports.version = version;
|
||||
// The main exported interface (under `self.acorn` when in the
|
||||
|
@ -890,7 +891,7 @@ function parseExpressionAt(input, pos, options) {
|
|||
}
|
||||
|
||||
// Acorn is organized as a tokenizer and a recursive-descent parser.
|
||||
// The `tokenize` export provides an interface to the tokenizer.
|
||||
// The `tokenizer` export provides an interface to the tokenizer.
|
||||
|
||||
function tokenizer(input, options) {
|
||||
return new _state.Parser(options, input);
|
||||
|
@ -940,7 +941,7 @@ var _whitespace = _dereq_("./whitespace");
|
|||
|
||||
var Position = (function () {
|
||||
function Position(line, col) {
|
||||
_classCallCheck(this, Position);
|
||||
|
||||
|
||||
this.line = line;
|
||||
this.column = col;
|
||||
|
@ -956,7 +957,7 @@ var Position = (function () {
|
|||
exports.Position = Position;
|
||||
|
||||
var SourceLocation = function SourceLocation(p, start, end) {
|
||||
_classCallCheck(this, SourceLocation);
|
||||
|
||||
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
|
@ -991,8 +992,6 @@ var _tokentype = _dereq_("./tokentype");
|
|||
|
||||
var _state = _dereq_("./state");
|
||||
|
||||
var _identifier = _dereq_("./identifier");
|
||||
|
||||
var _util = _dereq_("./util");
|
||||
|
||||
var pp = _state.Parser.prototype;
|
||||
|
@ -1006,7 +1005,6 @@ pp.toAssignable = function (node, isBinding) {
|
|||
case "Identifier":
|
||||
case "ObjectPattern":
|
||||
case "ArrayPattern":
|
||||
case "AssignmentPattern":
|
||||
break;
|
||||
|
||||
case "ObjectExpression":
|
||||
|
@ -1026,10 +1024,16 @@ pp.toAssignable = function (node, isBinding) {
|
|||
case "AssignmentExpression":
|
||||
if (node.operator === "=") {
|
||||
node.type = "AssignmentPattern";
|
||||
delete node.operator;
|
||||
delete node.operator
|
||||
// falls through to AssignmentPattern
|
||||
;
|
||||
} else {
|
||||
this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
|
||||
break;
|
||||
}
|
||||
|
||||
case "AssignmentPattern":
|
||||
if (node.right.type === "YieldExpression") this.raise(node.right.start, "Yield expression cannot be a default value");
|
||||
break;
|
||||
|
||||
case "ParenthesizedExpression":
|
||||
|
@ -1061,6 +1065,8 @@ pp.toAssignableList = function (exprList, isBinding) {
|
|||
if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") this.unexpected(arg.start);
|
||||
--end;
|
||||
}
|
||||
|
||||
if (isBinding && last.type === "RestElement" && last.argument.type !== "Identifier") this.unexpected(last.argument.start);
|
||||
}
|
||||
for (var i = 0; i < end; i++) {
|
||||
var elt = exprList[i];
|
||||
|
@ -1071,17 +1077,20 @@ pp.toAssignableList = function (exprList, isBinding) {
|
|||
|
||||
// Parses spread element.
|
||||
|
||||
pp.parseSpread = function (refShorthandDefaultPos) {
|
||||
pp.parseSpread = function (refDestructuringErrors) {
|
||||
var node = this.startNode();
|
||||
this.next();
|
||||
node.argument = this.parseMaybeAssign(refShorthandDefaultPos);
|
||||
node.argument = this.parseMaybeAssign(refDestructuringErrors);
|
||||
return this.finishNode(node, "SpreadElement");
|
||||
};
|
||||
|
||||
pp.parseRest = function () {
|
||||
pp.parseRest = function (allowNonIdent) {
|
||||
var node = this.startNode();
|
||||
this.next();
|
||||
node.argument = this.type === _tokentype.types.name || this.type === _tokentype.types.bracketL ? this.parseBindingAtom() : this.unexpected();
|
||||
|
||||
// RestElement inside of a function parameter must be an identifier
|
||||
if (allowNonIdent) node.argument = this.type === _tokentype.types.name ? this.parseIdent() : this.unexpected();else node.argument = this.type === _tokentype.types.name || this.type === _tokentype.types.bracketL ? this.parseBindingAtom() : this.unexpected();
|
||||
|
||||
return this.finishNode(node, "RestElement");
|
||||
};
|
||||
|
||||
|
@ -1107,7 +1116,7 @@ pp.parseBindingAtom = function () {
|
|||
}
|
||||
};
|
||||
|
||||
pp.parseBindingList = function (close, allowEmpty, allowTrailingComma) {
|
||||
pp.parseBindingList = function (close, allowEmpty, allowTrailingComma, allowNonIdent) {
|
||||
var elts = [],
|
||||
first = true;
|
||||
while (!this.eat(close)) {
|
||||
|
@ -1117,7 +1126,7 @@ pp.parseBindingList = function (close, allowEmpty, allowTrailingComma) {
|
|||
} else if (allowTrailingComma && this.afterTrailingComma(close)) {
|
||||
break;
|
||||
} else if (this.type === _tokentype.types.ellipsis) {
|
||||
var rest = this.parseRest();
|
||||
var rest = this.parseRest(allowNonIdent);
|
||||
this.parseBindingListItem(rest);
|
||||
elts.push(rest);
|
||||
this.expect(close);
|
||||
|
@ -1139,9 +1148,8 @@ pp.parseBindingListItem = function (param) {
|
|||
|
||||
pp.parseMaybeDefault = function (startPos, startLoc, left) {
|
||||
left = left || this.parseBindingAtom();
|
||||
if (!this.eat(_tokentype.types.eq)) return left;
|
||||
if (this.options.ecmaVersion < 6 || !this.eat(_tokentype.types.eq)) return left;
|
||||
var node = this.startNodeAt(startPos, startLoc);
|
||||
node.operator = "=";
|
||||
node.left = left;
|
||||
node.right = this.parseMaybeAssign();
|
||||
return this.finishNode(node, "AssignmentPattern");
|
||||
|
@ -1153,9 +1161,9 @@ pp.parseMaybeDefault = function (startPos, startLoc, left) {
|
|||
pp.checkLVal = function (expr, isBinding, checkClashes) {
|
||||
switch (expr.type) {
|
||||
case "Identifier":
|
||||
if (this.strict && (_identifier.reservedWords.strictBind(expr.name) || _identifier.reservedWords.strict(expr.name))) this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
|
||||
if (this.strict && this.reservedWordsStrictBind.test(expr.name)) this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
|
||||
if (checkClashes) {
|
||||
if (_util.has(checkClashes, expr.name)) this.raise(expr.start, "Argument name clash in strict mode");
|
||||
if (_util.has(checkClashes, expr.name)) this.raise(expr.start, "Argument name clash");
|
||||
checkClashes[expr.name] = true;
|
||||
}
|
||||
break;
|
||||
|
@ -1193,7 +1201,7 @@ pp.checkLVal = function (expr, isBinding, checkClashes) {
|
|||
}
|
||||
};
|
||||
|
||||
},{"./identifier":"/src\\identifier.js","./state":"/src\\state.js","./tokentype":"/src\\tokentype.js","./util":"/src\\util.js"}],"/src\\node.js":[function(_dereq_,module,exports){
|
||||
},{"./state":"/src\\state.js","./tokentype":"/src\\tokentype.js","./util":"/src\\util.js"}],"/src\\node.js":[function(_dereq_,module,exports){
|
||||
"use strict";
|
||||
|
||||
exports.__esModule = true;
|
||||
|
@ -1205,7 +1213,7 @@ var _state = _dereq_("./state");
|
|||
var _locutil = _dereq_("./locutil");
|
||||
|
||||
var Node = function Node(parser, pos, loc) {
|
||||
_classCallCheck(this, Node);
|
||||
|
||||
|
||||
this.type = "";
|
||||
this.start = pos;
|
||||
|
@ -1279,11 +1287,11 @@ var defaultOptions = {
|
|||
// `onTrailingComma` is similar to `onInsertedSemicolon`, but for
|
||||
// trailing commas.
|
||||
onTrailingComma: null,
|
||||
// By default, reserved words are not enforced. Disable
|
||||
// `allowReserved` to enforce them. When this option has the
|
||||
// value "never", reserved words and keywords can also not be
|
||||
// used as property names.
|
||||
allowReserved: true,
|
||||
// By default, reserved words are only enforced if ecmaVersion >= 5.
|
||||
// Set `allowReserved` to a boolean value to explicitly turn this on
|
||||
// an off. When this option has the value "never", reserved words
|
||||
// and keywords can also not be used as property names.
|
||||
allowReserved: null,
|
||||
// When enabled, a return at the top level is not considered an
|
||||
// error.
|
||||
allowReturnOutsideFunction: false,
|
||||
|
@ -1300,9 +1308,9 @@ var defaultOptions = {
|
|||
locations: true,
|
||||
// A function can be passed as `onToken` option, which will
|
||||
// cause Acorn to call that function with object in the same
|
||||
// format as tokenize() returns. Note that you are not
|
||||
// allowed to call the parser from the callback—that will
|
||||
// corrupt its internal state.
|
||||
// format as tokens returned from `tokenizer().getToken()`. Note
|
||||
// that you are not allowed to call the parser from the
|
||||
// callback—that will corrupt its internal state.
|
||||
onToken: null,
|
||||
// A function can be passed as `onComment` option, which will
|
||||
// cause Acorn to call that function with `(block, text, start,
|
||||
|
@ -1349,7 +1357,9 @@ function getOptions(opts) {
|
|||
var options = {};
|
||||
for (var opt in defaultOptions) {
|
||||
options[opt] = opts && _util.has(opts, opt) ? opts[opt] : defaultOptions[opt];
|
||||
}if (_util.isArray(options.onToken)) {
|
||||
}if (options.allowReserved == null) options.allowReserved = options.ecmaVersion < 5;
|
||||
|
||||
if (_util.isArray(options.onToken)) {
|
||||
(function () {
|
||||
var tokens = options.onToken;
|
||||
options.onToken = function (token) {
|
||||
|
@ -1466,6 +1476,18 @@ pp.unexpected = function (pos) {
|
|||
this.raise(pos != null ? pos : this.start, "Unexpected token");
|
||||
};
|
||||
|
||||
pp.checkPatternErrors = function (refDestructuringErrors, andThrow) {
|
||||
var pos = refDestructuringErrors && refDestructuringErrors.trailingComma;
|
||||
if (!andThrow) return !!pos;
|
||||
if (pos) this.raise(pos, "Trailing comma is not permitted in destructuring patterns");
|
||||
};
|
||||
|
||||
pp.checkExpressionErrors = function (refDestructuringErrors, andThrow) {
|
||||
var pos = refDestructuringErrors && refDestructuringErrors.shorthandAssign;
|
||||
if (!andThrow) return !!pos;
|
||||
if (pos) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns");
|
||||
};
|
||||
|
||||
},{"./state":"/src\\state.js","./tokentype":"/src\\tokentype.js","./whitespace":"/src\\whitespace.js"}],"/src\\state.js":[function(_dereq_,module,exports){
|
||||
"use strict";
|
||||
|
||||
|
@ -1485,19 +1507,31 @@ var _options = _dereq_("./options");
|
|||
var plugins = {};
|
||||
|
||||
exports.plugins = plugins;
|
||||
function keywordRegexp(words) {
|
||||
return new RegExp("^(" + words.replace(/ /g, "|") + ")$");
|
||||
}
|
||||
|
||||
var Parser = (function () {
|
||||
function Parser(options, input, startPos) {
|
||||
_classCallCheck(this, Parser);
|
||||
|
||||
this.options = _options.getOptions(options);
|
||||
this.sourceFile = this.options.sourceFile;
|
||||
this.isKeyword = _identifier.keywords[this.options.ecmaVersion >= 6 ? 6 : 5];
|
||||
this.isReservedWord = _identifier.reservedWords[this.options.ecmaVersion];
|
||||
|
||||
this.options = options = _options.getOptions(options);
|
||||
this.sourceFile = options.sourceFile;
|
||||
this.keywords = keywordRegexp(_identifier.keywords[options.ecmaVersion >= 6 ? 6 : 5]);
|
||||
var reserved = options.allowReserved ? "" : _identifier.reservedWords[options.ecmaVersion] + (options.sourceType == "module" ? " await" : "");
|
||||
this.reservedWords = keywordRegexp(reserved);
|
||||
var reservedStrict = (reserved ? reserved + " " : "") + _identifier.reservedWords.strict;
|
||||
this.reservedWordsStrict = keywordRegexp(reservedStrict);
|
||||
this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + _identifier.reservedWords.strictBind);
|
||||
this.input = String(input);
|
||||
|
||||
// Used to signal to callers of `readWord1` whether the word
|
||||
// contained any escape sequences. This is needed because words with
|
||||
// escape sequences must not be interpreted as keywords.
|
||||
this.containsEsc = false;
|
||||
|
||||
// Load plugins
|
||||
this.loadPlugins(this.options.plugins);
|
||||
this.loadPlugins(options.plugins);
|
||||
|
||||
// Set up token state
|
||||
|
||||
|
@ -1533,7 +1567,7 @@ var Parser = (function () {
|
|||
this.exprAllowed = true;
|
||||
|
||||
// Figure out if it's a module code.
|
||||
this.strict = this.inModule = this.options.sourceType === "module";
|
||||
this.strict = this.inModule = options.sourceType === "module";
|
||||
|
||||
// Used to signify the start of a potential arrow function
|
||||
this.potentialArrowAt = -1;
|
||||
|
@ -1544,9 +1578,19 @@ var Parser = (function () {
|
|||
this.labels = [];
|
||||
|
||||
// If enabled, skip leading hashbang line.
|
||||
if (this.pos === 0 && this.options.allowHashBang && this.input.slice(0, 2) === "#!") this.skipLineComment(2);
|
||||
if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") this.skipLineComment(2);
|
||||
}
|
||||
|
||||
// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them
|
||||
|
||||
Parser.prototype.isKeyword = function isKeyword(word) {
|
||||
return this.keywords.test(word);
|
||||
};
|
||||
|
||||
Parser.prototype.isReservedWord = function isReservedWord(word) {
|
||||
return this.reservedWords.test(word);
|
||||
};
|
||||
|
||||
Parser.prototype.extend = function extend(name, f) {
|
||||
this[name] = f(this[name]);
|
||||
};
|
||||
|
@ -1665,7 +1709,7 @@ pp.parseStatement = function (declaration, topLevel) {
|
|||
case _tokentype.types._import:
|
||||
if (!this.options.allowImportExportEverywhere) {
|
||||
if (!topLevel) this.raise(this.start, "'import' and 'export' may only appear at the top level");
|
||||
if (!this.inModule) this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'");
|
||||
// if (!this.inModule) this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'");
|
||||
}
|
||||
return starttype === _tokentype.types._import ? this.parseImport(node) : this.parseExport(node);
|
||||
|
||||
|
@ -1741,14 +1785,15 @@ pp.parseForStatement = function (node) {
|
|||
if ((this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && _init.declarations.length === 1 && !(varKind !== _tokentype.types._var && _init.declarations[0].init)) return this.parseForIn(node, _init);
|
||||
return this.parseFor(node, _init);
|
||||
}
|
||||
var refShorthandDefaultPos = { start: 0 };
|
||||
var init = this.parseExpression(true, refShorthandDefaultPos);
|
||||
var refDestructuringErrors = { shorthandAssign: 0, trailingComma: 0 };
|
||||
var init = this.parseExpression(true, refDestructuringErrors);
|
||||
if (this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) {
|
||||
this.checkPatternErrors(refDestructuringErrors, true);
|
||||
this.toAssignable(init);
|
||||
this.checkLVal(init);
|
||||
return this.parseForIn(node, init);
|
||||
} else if (refShorthandDefaultPos.start) {
|
||||
this.unexpected(refShorthandDefaultPos.start);
|
||||
} else {
|
||||
this.checkExpressionErrors(refDestructuringErrors, true);
|
||||
}
|
||||
return this.parseFor(node, init);
|
||||
};
|
||||
|
@ -1840,11 +1885,9 @@ pp.parseTryStatement = function (node) {
|
|||
clause.param = this.parseBindingAtom();
|
||||
this.checkLVal(clause.param, true);
|
||||
this.expect(_tokentype.types.parenR);
|
||||
clause.guard = null;
|
||||
clause.body = this.parseBlock();
|
||||
node.handler = this.finishNode(clause, "CatchClause");
|
||||
}
|
||||
node.guardedHandlers = empty;
|
||||
node.finalizer = this.eat(_tokentype.types._finally) ? this.parseBlock() : null;
|
||||
if (!node.handler && !node.finalizer) this.raise(node.start, "Missing catch or finally clause");
|
||||
return this.finishNode(node, "TryStatement");
|
||||
|
@ -1998,7 +2041,7 @@ pp.parseFunction = function (node, isStatement, allowExpressionBody) {
|
|||
|
||||
pp.parseFunctionParams = function (node) {
|
||||
this.expect(_tokentype.types.parenL);
|
||||
node.params = this.parseBindingList(_tokentype.types.parenR, false, false);
|
||||
node.params = this.parseBindingList(_tokentype.types.parenR, false, false, true);
|
||||
};
|
||||
|
||||
// Parse a class declaration or literal (depending on the
|
||||
|
@ -2049,6 +2092,7 @@ pp.parseClass = function (node, isStatement) {
|
|||
var start = method.value.start;
|
||||
if (method.kind === "get") this.raise(start, "getter should have no params");else this.raise(start, "setter should have exactly one param");
|
||||
}
|
||||
if (method.kind === "set" && method.value.params[0].type === "RestElement") this.raise(method.value.params[0].start, "Setter cannot use rest params");
|
||||
}
|
||||
}
|
||||
node.body = this.finishNode(classBody, "ClassBody");
|
||||
|
@ -2105,6 +2149,13 @@ pp.parseExport = function (node) {
|
|||
if (this.eatContextual("from")) {
|
||||
node.source = this.type === _tokentype.types.string ? this.parseExprAtom() : this.unexpected();
|
||||
} else {
|
||||
// check for keywords used as local names
|
||||
for (var i = 0; i < node.specifiers.length; i++) {
|
||||
if (this.keywords.test(node.specifiers[i].local.name) || this.reservedWords.test(node.specifiers[i].local.name)) {
|
||||
this.unexpected(node.specifiers[i].local.start);
|
||||
}
|
||||
}
|
||||
|
||||
node.source = null;
|
||||
}
|
||||
this.semicolon();
|
||||
|
@ -2145,7 +2196,6 @@ pp.parseImport = function (node) {
|
|||
if (this.type === _tokentype.types.string) {
|
||||
node.specifiers = empty;
|
||||
node.source = this.parseExprAtom();
|
||||
node.kind = "";
|
||||
} else {
|
||||
node.specifiers = this.parseImportSpecifiers();
|
||||
this.expectContextual("from");
|
||||
|
@ -2186,7 +2236,13 @@ pp.parseImportSpecifiers = function () {
|
|||
|
||||
var node = this.startNode();
|
||||
node.imported = this.parseIdent(true);
|
||||
node.local = this.eatContextual("as") ? this.parseIdent() : node.imported;
|
||||
if (this.eatContextual("as")) {
|
||||
node.local = this.parseIdent();
|
||||
} else {
|
||||
node.local = node.imported;
|
||||
if (this.isKeyword(node.local.name)) this.unexpected(node.local.start);
|
||||
if (this.reservedWordsStrict.test(node.local.name)) this.raise(node.local.start, "The keyword '" + node.local.name + "' is reserved");
|
||||
}
|
||||
this.checkLVal(node.local, true);
|
||||
nodes.push(this.finishNode(node, "ImportSpecifier"));
|
||||
}
|
||||
|
@ -2211,7 +2267,7 @@ var _tokentype = _dereq_("./tokentype");
|
|||
var _whitespace = _dereq_("./whitespace");
|
||||
|
||||
var TokContext = function TokContext(token, isExpr, preserveSpace, override) {
|
||||
_classCallCheck(this, TokContext);
|
||||
|
||||
|
||||
this.token = token;
|
||||
this.isExpr = !!isExpr;
|
||||
|
@ -2326,7 +2382,7 @@ var _whitespace = _dereq_("./whitespace");
|
|||
// used for the onToken callback and the external tokenizer.
|
||||
|
||||
var Token = function Token(p) {
|
||||
_classCallCheck(this, Token);
|
||||
|
||||
|
||||
this.type = p.type;
|
||||
this.value = p.value;
|
||||
|
@ -2720,13 +2776,13 @@ pp.finishOp = function (type, size) {
|
|||
// Parse a regular expression. Some context-awareness is necessary,
|
||||
// since a '/' inside a '[]' set does not end the expression.
|
||||
|
||||
function tryCreateRegexp(src, flags, throwErrorAt) {
|
||||
function tryCreateRegexp(src, flags, throwErrorAt, parser) {
|
||||
try {
|
||||
return new RegExp(src, flags);
|
||||
} catch (e) {
|
||||
if (throwErrorAt !== undefined) {
|
||||
if (e instanceof SyntaxError) this.raise(throwErrorAt, "Error parsing regular expression: " + e.message);
|
||||
this.raise(e);
|
||||
if (e instanceof SyntaxError) parser.raise(throwErrorAt, "Error parsing regular expression: " + e.message);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2756,8 +2812,8 @@ pp.readRegexp = function () {
|
|||
var mods = this.readWord1();
|
||||
var tmp = content;
|
||||
if (mods) {
|
||||
var validFlags = /^[gmsiy]*$/;
|
||||
if (this.options.ecmaVersion >= 6) validFlags = /^[gmsiyu]*$/;
|
||||
var validFlags = /^[gim]*$/;
|
||||
if (this.options.ecmaVersion >= 6) validFlags = /^[gimuy]*$/;
|
||||
if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag");
|
||||
if (mods.indexOf("u") >= 0 && !regexpUnicodeSupport) {
|
||||
// Replace each astral symbol and every Unicode escape sequence that
|
||||
|
@ -2768,7 +2824,7 @@ pp.readRegexp = function () {
|
|||
// negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
|
||||
// perfectly valid pattern that is equivalent to `[a-b]`, but it would
|
||||
// be replaced by `[x-b]` which throws an error.
|
||||
tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, function (match, code, offset) {
|
||||
tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, function (_match, code, offset) {
|
||||
code = Number("0x" + code);
|
||||
if (code > 0x10FFFF) _this.raise(start + offset + 3, "Code point out of bounds");
|
||||
return "x";
|
||||
|
@ -2781,7 +2837,7 @@ pp.readRegexp = function () {
|
|||
// Rhino's regular expression parser is flaky and throws uncatchable exceptions,
|
||||
// so don't do detection if we are running under Rhino
|
||||
if (!isRhino) {
|
||||
tryCreateRegexp(tmp, undefined, start);
|
||||
tryCreateRegexp(tmp, undefined, start, this);
|
||||
// Get a regular expression object for this pattern-flag pair, or `null` in
|
||||
// case the current environment doesn't support the flags it uses.
|
||||
value = tryCreateRegexp(content, mods);
|
||||
|
@ -2985,7 +3041,7 @@ pp.readEscapedChar = function (inTemplate) {
|
|||
octalStr = octalStr.slice(0, -1);
|
||||
octal = parseInt(octalStr, 8);
|
||||
}
|
||||
if (octal > 0 && (this.strict || inTemplate)) {
|
||||
if (octalStr !== "0" && (this.strict || inTemplate)) {
|
||||
this.raise(this.pos - 2, "Octal literal in strict mode");
|
||||
}
|
||||
this.pos += octalStr.length - 1;
|
||||
|
@ -3004,20 +3060,14 @@ pp.readHexChar = function (len) {
|
|||
return n;
|
||||
};
|
||||
|
||||
// Used to signal to callers of `readWord1` whether the word
|
||||
// contained any escape sequences. This is needed because words with
|
||||
// escape sequences must not be interpreted as keywords.
|
||||
|
||||
var containsEsc;
|
||||
|
||||
// Read an identifier, and return it as a string. Sets `containsEsc`
|
||||
// Read an identifier, and return it as a string. Sets `this.containsEsc`
|
||||
// to whether the word contained a '\u' escape.
|
||||
//
|
||||
// Incrementally adds only escaped chars, adding other chunks as-is
|
||||
// as a micro-optimization.
|
||||
|
||||
pp.readWord1 = function () {
|
||||
containsEsc = false;
|
||||
this.containsEsc = false;
|
||||
var word = "",
|
||||
first = true,
|
||||
chunkStart = this.pos;
|
||||
|
@ -3028,7 +3078,7 @@ pp.readWord1 = function () {
|
|||
this.pos += ch <= 0xffff ? 1 : 2;
|
||||
} else if (ch === 92) {
|
||||
// "\"
|
||||
containsEsc = true;
|
||||
this.containsEsc = true;
|
||||
word += this.input.slice(chunkStart, this.pos);
|
||||
var escStart = this.pos;
|
||||
if (this.input.charCodeAt(++this.pos) != 117) // "u"
|
||||
|
@ -3052,7 +3102,7 @@ pp.readWord1 = function () {
|
|||
pp.readWord = function () {
|
||||
var word = this.readWord1();
|
||||
var type = _tokentype.types.name;
|
||||
if ((this.options.ecmaVersion >= 6 || !containsEsc) && this.isKeyword(word)) type = _tokentype.keywords[word];
|
||||
if ((this.options.ecmaVersion >= 6 || !this.containsEsc) && this.keywords.test(word)) type = _tokentype.keywords[word];
|
||||
return this.finishToken(type, word);
|
||||
};
|
||||
|
||||
|
@ -3071,6 +3121,11 @@ pp.readWord = function () {
|
|||
// be followed by an expression (thus, a slash after them would be a
|
||||
// regular expression).
|
||||
//
|
||||
// The `startsExpr` property is used to check if the token ends a
|
||||
// `yield` expression. It is set on all token types that either can
|
||||
// directly start an expression (like a quotation mark) or can
|
||||
// continue an expression (like the body of a string).
|
||||
//
|
||||
// `isLoop` marks a keyword as starting a loop, which is important
|
||||
// to know when parsing a label, in order to allow or disallow
|
||||
// continue jumps to that label.
|
||||
|
@ -3084,7 +3139,6 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
|
|||
var TokenType = function TokenType(label) {
|
||||
var conf = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
||||
|
||||
_classCallCheck(this, TokenType);
|
||||
|
||||
this.label = label;
|
||||
this.keyword = conf.keyword;
|
||||
|
@ -3183,7 +3237,7 @@ kw("catch");
|
|||
kw("continue");
|
||||
kw("debugger");
|
||||
kw("default", beforeExpr);
|
||||
kw("do", { isLoop: true });
|
||||
kw("do", { isLoop: true, beforeExpr: true });
|
||||
kw("else", beforeExpr);
|
||||
kw("finally");
|
||||
kw("for", { isLoop: true });
|
||||
|
@ -3255,5 +3309,4 @@ exports.nonASCIIwhitespace = nonASCIIwhitespace;
|
|||
|
||||
},{}]},{},["/src\\index.js"])("/src\\index.js")
|
||||
});
|
||||
|
||||
})
|
||||
});
|
|
@ -1,8 +1,9 @@
|
|||
define(["require", "exports", "module", "./acorn"], function(require, exports, module) {
|
||||
|
||||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.acorn || (g.acorn = {})).loose = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"/src\\index.js":[function(_dereq_,module,exports){
|
||||
"use strict";
|
||||
|
||||
module.exports = typeof acorn != "undefined" ? acorn : _dereq_("./acorn");
|
||||
module.exports = typeof acorn != 'undefined' ? acorn : require("./acorn");
|
||||
|
||||
},{}],"/src\\loose\\expression.js":[function(_dereq_,module,exports){
|
||||
"use strict";
|
||||
|
@ -15,26 +16,17 @@ var _ = _dereq_("..");
|
|||
|
||||
var lp = _state.LooseParser.prototype;
|
||||
|
||||
lp.checkLVal = function (expr, binding) {
|
||||
lp.checkLVal = function (expr) {
|
||||
if (!expr) return expr;
|
||||
switch (expr.type) {
|
||||
case "Identifier":
|
||||
return expr;
|
||||
|
||||
case "MemberExpression":
|
||||
return binding ? this.dummyIdent() : expr;
|
||||
return expr;
|
||||
|
||||
case "ParenthesizedExpression":
|
||||
expr.expression = this.checkLVal(expr.expression, binding);
|
||||
expr.expression = this.checkLVal(expr.expression);
|
||||
return expr;
|
||||
|
||||
// FIXME recursively check contents
|
||||
case "ObjectPattern":
|
||||
case "ArrayPattern":
|
||||
case "RestElement":
|
||||
case "AssignmentPattern":
|
||||
if (this.options.ecmaVersion >= 6) return expr;
|
||||
|
||||
default:
|
||||
return this.dummyIdent();
|
||||
}
|
||||
|
@ -200,6 +192,17 @@ lp.parseExprAtom = function () {
|
|||
return this.finishNode(node, type);
|
||||
|
||||
case _.tokTypes.name:
|
||||
// quick hack to allow async and await
|
||||
if (this.tok.value == "async" && /^[ \t]+function\b/.test(this.input.slice(this.tok.end))) {
|
||||
node = this.startNode();
|
||||
this.next();
|
||||
return this.parseExprAtom();
|
||||
}
|
||||
if (this.tok.value == "await" && /^[ \t]+[\w\x1f-\uffff]/.test(this.input.slice(this.tok.end))) {
|
||||
node = this.startNode();
|
||||
this.next();
|
||||
return this.parseExprAtom();
|
||||
}
|
||||
var start = this.storeCurrentPos();
|
||||
var id = this.parseIdent();
|
||||
return this.eat(_.tokTypes.arrow) ? this.parseArrowExpression(this.startNodeAt(start), [id]) : id;
|
||||
|
@ -440,32 +443,29 @@ lp.initFunction = function (node) {
|
|||
// if possible.
|
||||
|
||||
lp.toAssignable = function (node, binding) {
|
||||
if (this.options.ecmaVersion >= 6 && node) {
|
||||
switch (node.type) {
|
||||
case "ObjectExpression":
|
||||
node.type = "ObjectPattern";
|
||||
var props = node.properties;
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
this.toAssignable(props[i].value, binding);
|
||||
}break;
|
||||
|
||||
case "ArrayExpression":
|
||||
node.type = "ArrayPattern";
|
||||
this.toAssignableList(node.elements, binding);
|
||||
break;
|
||||
|
||||
case "SpreadElement":
|
||||
node.type = "RestElement";
|
||||
node.argument = this.toAssignable(node.argument, binding);
|
||||
break;
|
||||
|
||||
case "AssignmentExpression":
|
||||
node.type = "AssignmentPattern";
|
||||
delete node.operator;
|
||||
break;
|
||||
if (!node || node.type == "Identifier" || node.type == "MemberExpression" && !binding) {} else if (node.type == "ParenthesizedExpression") {
|
||||
node.expression = this.toAssignable(node.expression, binding);
|
||||
} else if (this.options.ecmaVersion < 6) {
|
||||
return this.dummyIdent();
|
||||
} else if (node.type == "ObjectExpression") {
|
||||
node.type = "ObjectPattern";
|
||||
var props = node.properties;
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
props[i].value = this.toAssignable(props[i].value, binding);
|
||||
}
|
||||
} else if (node.type == "ArrayExpression") {
|
||||
node.type = "ArrayPattern";
|
||||
this.toAssignableList(node.elements, binding);
|
||||
} else if (node.type == "SpreadElement") {
|
||||
node.type = "RestElement";
|
||||
node.argument = this.toAssignable(node.argument, binding);
|
||||
} else if (node.type == "AssignmentExpression") {
|
||||
node.type = "AssignmentPattern";
|
||||
delete node.operator;
|
||||
} else {
|
||||
return this.dummyIdent();
|
||||
}
|
||||
return this.checkLVal(node, binding);
|
||||
return node;
|
||||
};
|
||||
|
||||
lp.toAssignableList = function (exprList, binding) {
|
||||
|
@ -527,6 +527,8 @@ lp.parseExprList = function (close, allowEmpty) {
|
|||
return elts;
|
||||
};
|
||||
|
||||
// Okay
|
||||
|
||||
},{"..":"/src\\index.js","./parseutil":"/src\\loose\\parseutil.js","./state":"/src\\loose\\state.js"}],"/src\\loose\\index.js":[function(_dereq_,module,exports){
|
||||
// Acorn: Loose parser
|
||||
//
|
||||
|
@ -579,6 +581,7 @@ _dereq_("./statement");
|
|||
_dereq_("./expression");
|
||||
|
||||
exports.LooseParser = _state.LooseParser;
|
||||
exports.pluginsLoose = _state.pluginsLoose;
|
||||
|
||||
acorn.defaultOptions.tabSize = 4;
|
||||
|
||||
|
@ -590,6 +593,7 @@ function parse_dammit(input, options) {
|
|||
|
||||
acorn.parse_dammit = parse_dammit;
|
||||
acorn.LooseParser = _state.LooseParser;
|
||||
acorn.pluginsLoose = _state.pluginsLoose;
|
||||
|
||||
},{"..":"/src\\index.js","./expression":"/src\\loose\\expression.js","./state":"/src\\loose\\state.js","./statement":"/src\\loose\\statement.js","./tokenize":"/src\\loose\\tokenize.js"}],"/src\\loose\\parseutil.js":[function(_dereq_,module,exports){
|
||||
"use strict";
|
||||
|
@ -610,9 +614,14 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
|
|||
|
||||
var _ = _dereq_("..");
|
||||
|
||||
// Registered plugins
|
||||
var pluginsLoose = {};
|
||||
|
||||
exports.pluginsLoose = pluginsLoose;
|
||||
|
||||
var LooseParser = (function () {
|
||||
function LooseParser(input, options) {
|
||||
_classCallCheck(this, LooseParser);
|
||||
|
||||
|
||||
this.toks = _.tokenizer(input, options);
|
||||
this.options = this.toks.options;
|
||||
|
@ -627,6 +636,9 @@ var LooseParser = (function () {
|
|||
this.curIndent = 0;
|
||||
this.curLineStart = 0;
|
||||
this.nextLineStart = this.lineEnd(this.curLineStart) + 1;
|
||||
// Load plugins
|
||||
this.options.pluginsLoose = options.pluginsLoose || {};
|
||||
this.loadPlugins(this.options.pluginsLoose);
|
||||
}
|
||||
|
||||
LooseParser.prototype.startNode = function startNode() {
|
||||
|
@ -653,10 +665,26 @@ var LooseParser = (function () {
|
|||
return node;
|
||||
};
|
||||
|
||||
LooseParser.prototype.dummyIdent = function dummyIdent() {
|
||||
LooseParser.prototype.dummyNode = function dummyNode(type) {
|
||||
var dummy = this.startNode();
|
||||
dummy.type = type;
|
||||
dummy.end = dummy.start;
|
||||
if (this.options.locations) dummy.loc.end = dummy.loc.start;
|
||||
if (this.options.ranges) dummy.range[1] = dummy.start;
|
||||
this.last = { type: _.tokTypes.name, start: dummy.start, end: dummy.start, loc: dummy.loc };
|
||||
return dummy;
|
||||
};
|
||||
|
||||
LooseParser.prototype.dummyIdent = function dummyIdent() {
|
||||
var dummy = this.dummyNode("Identifier");
|
||||
dummy.name = "✖";
|
||||
return this.finishNode(dummy, "Identifier");
|
||||
return dummy;
|
||||
};
|
||||
|
||||
LooseParser.prototype.dummyString = function dummyString() {
|
||||
var dummy = this.dummyNode("Literal");
|
||||
dummy.value = dummy.raw = "✖";
|
||||
return dummy;
|
||||
};
|
||||
|
||||
LooseParser.prototype.eat = function eat(type) {
|
||||
|
@ -732,6 +760,18 @@ var LooseParser = (function () {
|
|||
return true;
|
||||
};
|
||||
|
||||
LooseParser.prototype.extend = function extend(name, f) {
|
||||
this[name] = f(this[name]);
|
||||
};
|
||||
|
||||
LooseParser.prototype.loadPlugins = function loadPlugins(pluginConfigs) {
|
||||
for (var _name in pluginConfigs) {
|
||||
var plugin = pluginsLoose[_name];
|
||||
if (!plugin) throw new Error("Plugin '" + _name + "' not found");
|
||||
plugin(this, pluginConfigs[_name]);
|
||||
}
|
||||
};
|
||||
|
||||
return LooseParser;
|
||||
})();
|
||||
|
||||
|
@ -870,7 +910,6 @@ lp.parseStatement = function () {
|
|||
this.expect(_.tokTypes.parenL);
|
||||
clause.param = this.toAssignable(this.parseExprAtom(), true);
|
||||
this.expect(_.tokTypes.parenR);
|
||||
clause.guard = null;
|
||||
clause.body = this.parseBlock();
|
||||
node.handler = this.finishNode(clause, "CatchClause");
|
||||
}
|
||||
|
@ -1104,7 +1143,7 @@ lp.parseImport = function () {
|
|||
this.eat(_.tokTypes.comma);
|
||||
}
|
||||
node.specifiers = this.parseImportSpecifierList();
|
||||
node.source = this.eatContextual("from") ? this.parseExprAtom() : null;
|
||||
node.source = this.eatContextual("from") && this.tok.type == _.tokTypes.string ? this.parseExprAtom() : this.dummyString();
|
||||
if (elt) node.specifiers.unshift(elt);
|
||||
}
|
||||
this.semicolon();
|
||||
|
@ -1128,7 +1167,7 @@ lp.parseImportSpecifierList = function () {
|
|||
while (!this.closes(_.tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) {
|
||||
var elt = this.startNode();
|
||||
if (this.eat(_.tokTypes.star)) {
|
||||
if (this.eatContextual("as")) elt.local = this.parseIdent();
|
||||
elt.local = this.eatContextual("as") ? this.parseIdent() : this.dummyIdent();
|
||||
this.finishNode(elt, "ImportNamespaceSpecifier");
|
||||
} else {
|
||||
if (this.isContextual("from")) break;
|
||||
|
@ -1276,5 +1315,4 @@ lp.lookAhead = function (n) {
|
|||
|
||||
},{"..":"/src\\index.js","./state":"/src\\loose\\state.js"}]},{},["/src\\loose\\index.js"])("/src\\loose\\index.js")
|
||||
});
|
||||
|
||||
})
|
||||
});
|
|
@ -1,4 +1,5 @@
|
|||
define(["require", "exports", "module", "./acorn"], function(require, exports, module) {
|
||||
|
||||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.acorn || (g.acorn = {})).walk = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"/src\\walk\\index.js":[function(_dereq_,module,exports){
|
||||
// AST walker module for Mozilla Parser API compatible trees
|
||||
|
||||
|
@ -79,7 +80,7 @@ function makeTest(test) {
|
|||
}
|
||||
|
||||
var Found = function Found(node, state) {
|
||||
_classCallCheck(this, Found);
|
||||
|
||||
|
||||
this.node = node;this.state = state;
|
||||
};
|
||||
|
@ -95,7 +96,7 @@ function findNodeAt(node, start, end, test, base, state) {
|
|||
;(function c(node, st, override) {
|
||||
var type = override || node.type;
|
||||
if ((start == null || node.start <= start) && (end == null || node.end >= end)) base[type](node, st, c);
|
||||
if (test(type, node) && (start == null || node.start == start) && (end == null || node.end == end)) throw new Found(node, st);
|
||||
if ((start == null || node.start == start) && (end == null || node.end == end) && test(type, node)) throw new Found(node, st);
|
||||
})(node, state);
|
||||
} catch (e) {
|
||||
if (e instanceof Found) return e;
|
||||
|
@ -247,20 +248,28 @@ base.FunctionDeclaration = function (node, st, c) {
|
|||
};
|
||||
base.VariableDeclaration = function (node, st, c) {
|
||||
for (var i = 0; i < node.declarations.length; ++i) {
|
||||
var decl = node.declarations[i];
|
||||
c(decl.id, st, "Pattern");
|
||||
if (decl.init) c(decl.init, st, "Expression");
|
||||
c(node.declarations[i], st);
|
||||
}
|
||||
};
|
||||
base.VariableDeclarator = function (node, st, c) {
|
||||
c(node.id, st, "Pattern");
|
||||
if (node.init) c(node.init, st, "Expression");
|
||||
};
|
||||
|
||||
base.Function = function (node, st, c) {
|
||||
if (node.id) c(node.id, st, "Pattern");
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
c(node.params[i], st, "Pattern");
|
||||
}c(node.body, st, "ScopeBody");
|
||||
}c(node.body, st, node.expression ? "ScopeExpression" : "ScopeBody");
|
||||
};
|
||||
// FIXME drop these node types in next major version
|
||||
// (They are awkward, and in ES6 every block can be a scope.)
|
||||
base.ScopeBody = function (node, st, c) {
|
||||
return c(node, st, "Statement");
|
||||
};
|
||||
base.ScopeExpression = function (node, st, c) {
|
||||
return c(node, st, "Expression");
|
||||
};
|
||||
|
||||
base.Pattern = function (node, st, c) {
|
||||
if (node.type == "Identifier") c(node, st, "VariablePattern");else if (node.type == "MemberExpression") c(node, st, "MemberPattern");else c(node, st);
|
||||
|
@ -328,12 +337,16 @@ base.MemberExpression = function (node, st, c) {
|
|||
if (node.computed) c(node.property, st, "Expression");
|
||||
};
|
||||
base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) {
|
||||
if (node.declaration) c(node.declaration, st);
|
||||
if (node.declaration) c(node.declaration, st, node.type == "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression");
|
||||
if (node.source) c(node.source, st, "Expression");
|
||||
};
|
||||
base.ExportAllDeclaration = function (node, st, c) {
|
||||
c(node.source, st, "Expression");
|
||||
};
|
||||
base.ImportDeclaration = function (node, st, c) {
|
||||
for (var i = 0; i < node.specifiers.length; i++) {
|
||||
c(node.specifiers[i], st);
|
||||
}
|
||||
}c(node.source, st, "Expression");
|
||||
};
|
||||
base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.Literal = ignore;
|
||||
|
||||
|
|
|
@ -99,12 +99,15 @@ module.exports = {
|
|||
assert.equal(parser.parse("if(").toString(), '[If(Var("✖"),Block([]),None())]');
|
||||
// todo should this be broken if and a function outside?
|
||||
assert.equal(parser.parse("if(hello.\nfunction hello() { return 0; }").toString(), '[If(PropAccess(Var("hello"),"✖"),Function("hello",[],[Return(Num("0"))]),None())]');
|
||||
assert.equal(parser.parse("var\nfunction hello() {}").toString(), '[VarDecls([]),Function("hello",[],[])]');
|
||||
// assert.equal(parser.parse("var\nfunction hello() {}").toString(), '[VarDecls([]),Function("hello",[],[])]');
|
||||
},
|
||||
"test parse literals": function() {
|
||||
assert.equal(parser.parse("true").toString(), '[Var("true")]');
|
||||
assert.equal(parser.parse("15").toString(), '[Num("15")]');
|
||||
assert.equal(parser.parse("15.5").toString(), '[Num("15.5")]');
|
||||
},
|
||||
"test es7": function() {
|
||||
assert.equal(parser.parse("async function a(x) {await y()}").toString(), '[Function("a",[FArg("x")],[Call(Var("y"),[])])]');
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
"url" : "http://github.com/ajaxorg/treehugger.git"
|
||||
},
|
||||
"engines" : {
|
||||
"node" : ">= 0.4.0"
|
||||
"node" : ">= 0.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node lib/treehugger/js/parse_test.js",
|
||||
"acorn": "node ../acorn/bin/build-acorn.js ; mv ../acorn/dist/* lib/acorn/dist"
|
||||
}
|
||||
}
|
||||
|
|
41
package.json
41
package.json
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "c9",
|
||||
"description": "New Cloud9 Client",
|
||||
"version": "3.1.838",
|
||||
"version": "3.1.1007",
|
||||
"author": "Ajax.org B.V. <info@ajax.org>",
|
||||
"private": true,
|
||||
"main": "bin/c9",
|
||||
|
@ -20,6 +20,7 @@
|
|||
"engine.io": "1.5.3",
|
||||
"engine.io-client": "1.5.3",
|
||||
"eslint": "git://github.com/cloud9ide/eslint.git#dc500e81162bf0cb4747a4a415c121b0c46975cb",
|
||||
"jsonm": "1.0.6",
|
||||
"http-error": "~0.0.5",
|
||||
"less": "^2.4.0",
|
||||
"mime": "~1.2.9",
|
||||
|
@ -55,23 +56,23 @@
|
|||
"c9"
|
||||
],
|
||||
"c9plugins": {
|
||||
"c9.ide.language": "#266fd7b05f",
|
||||
"c9.ide.language.css": "#a649f2a710",
|
||||
"c9.ide.language.generic": "#f1715e2f7d",
|
||||
"c9.ide.language.html": "#0f4078c187",
|
||||
"c9.ide.language": "#9953b57ae9",
|
||||
"c9.ide.language.css": "#be07d72209",
|
||||
"c9.ide.language.generic": "#3771ac5199",
|
||||
"c9.ide.language.html": "#9be847c0ce",
|
||||
"c9.ide.language.html.diff": "#24f3608d26",
|
||||
"c9.ide.language.javascript": "#2b77bdb96a",
|
||||
"c9.ide.language.javascript.immediate": "#0535804ada",
|
||||
"c9.ide.language.javascript.eslint": "#3ec4557969",
|
||||
"c9.ide.language.javascript.tern": "#63ae1e6b8e",
|
||||
"c9.ide.language.javascript.infer": "#3d137523df",
|
||||
"c9.ide.language.jsonalyzer": "#492c4b0956",
|
||||
"c9.ide.collab": "#30efed939e",
|
||||
"c9.ide.language.javascript": "#1a0b1584c2",
|
||||
"c9.ide.language.javascript.immediate": "#c8b1e5767a",
|
||||
"c9.ide.language.javascript.eslint": "#8d35953ff4",
|
||||
"c9.ide.language.javascript.tern": "#805d77e206",
|
||||
"c9.ide.language.javascript.infer": "#fd5cd9e3d9",
|
||||
"c9.ide.language.jsonalyzer": "#0a130ac606",
|
||||
"c9.ide.collab": "#10c224f9b8",
|
||||
"c9.ide.local": "#a6e689e33b",
|
||||
"c9.ide.find": "#e33fbaed2f",
|
||||
"c9.ide.find.infiles": "#c3bf17286d",
|
||||
"c9.ide.find.replace": "#8cbce45290",
|
||||
"c9.ide.run.debug": "#3e06ddc0d2",
|
||||
"c9.ide.run.debug": "#8b77a8379d",
|
||||
"c9.automate": "#47e2c429c9",
|
||||
"c9.ide.ace.emmet": "#6dc4585e02",
|
||||
"c9.ide.ace.gotoline": "#a8ff07c8f4",
|
||||
|
@ -86,31 +87,31 @@
|
|||
"c9.ide.dialog.wizard": "#7667ec79a8",
|
||||
"c9.ide.fontawesome": "#781602c5d8",
|
||||
"c9.ide.format": "#5ec97fb083",
|
||||
"c9.ide.help.support": "#0c311f7165",
|
||||
"c9.ide.help.support": "#98a1b45962",
|
||||
"c9.ide.imgeditor": "#612e75ef4f",
|
||||
"c9.ide.immediate": "#a962119bec",
|
||||
"c9.ide.installer": "#0fde9f0067",
|
||||
"c9.ide.language.python": "#20c876d856",
|
||||
"c9.ide.language.python": "#7b6460bab3",
|
||||
"c9.ide.language.go": "#undefined",
|
||||
"c9.ide.mount": "#e1b9ccf731",
|
||||
"c9.ide.navigate": "#38ae100ea1",
|
||||
"c9.ide.newresource": "#981a408a7b",
|
||||
"c9.ide.openfiles": "#7fa4a97fed",
|
||||
"c9.ide.preview": "#8f87ff2f6a",
|
||||
"c9.ide.preview.browser": "#cec211a76a",
|
||||
"c9.ide.preview.browser": "#c5b9a129de",
|
||||
"c9.ide.preview.markdown": "#bc846e1562",
|
||||
"c9.ide.pubsub": "#a85fb27eca",
|
||||
"c9.ide.readonly": "#e67bb593bd",
|
||||
"c9.ide.recentfiles": "#7c099abf40",
|
||||
"c9.ide.remote": "#301d2ab519",
|
||||
"c9.ide.processlist": "#2b12cd1bdd",
|
||||
"c9.ide.run": "#f39a46d09e",
|
||||
"c9.ide.run": "#453aa5f604",
|
||||
"c9.ide.run.build": "#0598fff697",
|
||||
"c9.ide.run.debug.xdebug": "#70aeb327c0",
|
||||
"c9.ide.run.debug.xdebug": "#5553240abe",
|
||||
"c9.ide.save": "#9461acd953",
|
||||
"c9.ide.scm": "#930a9e6f00",
|
||||
"c9.ide.terminal.monitor": "#2332e52331",
|
||||
"c9.ide.test": "#5b4c724bf6",
|
||||
"c9.ide.terminal.monitor": "#e26502f0df",
|
||||
"c9.ide.test": "#8f21f662d3",
|
||||
"c9.ide.test.mocha": "#fc053b23d2",
|
||||
"c9.ide.theme.flat": "#92cda0fb40",
|
||||
"c9.ide.threewaymerge": "#229382aa0b",
|
||||
|
|
|
@ -598,7 +598,7 @@ define(function(require, exports, module) {
|
|||
|
||||
api[type].get("persistent/" + apiKey, function(err, data){
|
||||
if (err) return callback(err);
|
||||
try { callback(null, JSON.stringify(data)); }
|
||||
try { callback(null, JSON.parse(data)); }
|
||||
catch(e){ return callback(e); }
|
||||
});
|
||||
}
|
||||
|
@ -613,7 +613,11 @@ define(function(require, exports, module) {
|
|||
else if (context == "workspace") type = "project";
|
||||
else throw new Error("Unsupported context: " + context);
|
||||
|
||||
api[type].put("persistent/" + apiKey, { data: JSON.stringify(data) }, callback);
|
||||
api[type].put("persistent/" + apiKey, {
|
||||
body: {
|
||||
data: JSON.stringify(data)
|
||||
}
|
||||
}, callback);
|
||||
}
|
||||
|
||||
/***** Register and define API *****/
|
||||
|
|
|
@ -629,6 +629,14 @@ define(function(require, exports, module) {
|
|||
});
|
||||
} else if (key === "children" || key === "isSelected") {
|
||||
prop = null;
|
||||
} else if (Object.prototype.toString.call(node[key]) == "[object Date]") {
|
||||
// why Date ends up here?
|
||||
reportError(new Error("Date in fs cache"), {
|
||||
key: key,
|
||||
value: node[key],
|
||||
path: node.path,
|
||||
hasParentProp: !!node.parent,
|
||||
});
|
||||
} else {
|
||||
prop = lang.deepCopy(node[key]);
|
||||
}
|
||||
|
@ -637,9 +645,9 @@ define(function(require, exports, module) {
|
|||
return copy;
|
||||
}
|
||||
|
||||
function clear(){
|
||||
function clear() {
|
||||
var all = model.visibleItems;
|
||||
for (var i = all.length; i--; ) {
|
||||
for (var i = all.length; i--;) {
|
||||
if (model.isOpen(all[i]))
|
||||
model.collapse(all[i]);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ define(function(require, exports, module) {
|
|||
var Plugin = imports.Plugin;
|
||||
|
||||
require("ace/lib/es5-shim");
|
||||
require("ace/lib/es6-shim");
|
||||
var useragent = require("ace/lib/useragent");
|
||||
var dom = require("ace/lib/dom");
|
||||
|
||||
|
|
|
@ -122,10 +122,10 @@ define(function(require, exports, module) {
|
|||
|
||||
metrics.increment("dialog.error");
|
||||
|
||||
errorHandler.log(new Error("Error dialog shown"), {
|
||||
message: message,
|
||||
messageString: getMessageString(message),
|
||||
});
|
||||
// errorHandler.log(new Error("Error dialog shown"), {
|
||||
// message: message,
|
||||
// messageString: getMessageString(message),
|
||||
// });
|
||||
}
|
||||
|
||||
hide(function() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
define(function(require, exports, module) {
|
||||
main.consumes = ["Plugin", "c9", "menus", "layout", "ui", "http"];
|
||||
main.consumes = ["Plugin", "c9", "menus", "layout", "ui", "http", "c9.analytics"];
|
||||
main.provides = ["help"];
|
||||
return main;
|
||||
|
||||
|
@ -9,6 +9,7 @@ define(function(require, exports, module) {
|
|||
var http = imports.http;
|
||||
var ui = imports.ui;
|
||||
var menus = imports.menus;
|
||||
var analytics = imports["c9.analytics"];
|
||||
|
||||
var markup = require("text!./help.xml");
|
||||
var css = require("text!./style.css");
|
||||
|
@ -40,50 +41,39 @@ define(function(require, exports, module) {
|
|||
}), 100, plugin);
|
||||
|
||||
var c = 0;
|
||||
menus.addItemByPath("Support/Status Page", new ui.item({
|
||||
menus.addItemByPath("Support/Check Cloud9 Status", new ui.item({
|
||||
onclick: function(){window.open('http://status.c9.io'); }
|
||||
}), c += 100, plugin);
|
||||
|
||||
// menus.addItemByPath("Support/~", new ui.divider(), c += 100, plugin);
|
||||
// ide.addEventListener("hook.ext/keybindings_default/keybindings_default", function(c, e) {
|
||||
// menus.addItemByPath("Support/Keyboard Shortcuts", new ui.item({ onclick : function(){ e.ext.keybindings(); }}), c);
|
||||
// }.bind(this, c += 100), plugin);
|
||||
menus.addItemByPath("Support/~", new ui.divider(), c += 100, plugin);
|
||||
|
||||
menus.addItemByPath("Support/Cloud9 Community", new ui.item({
|
||||
menus.addItemByPath("Support/Get Help (Community)", new ui.item({
|
||||
onclick: function(){
|
||||
analytics.track("Visited Cloud9 Community");
|
||||
window.open("https://community.c9.io");
|
||||
}
|
||||
}), c += 100, plugin);
|
||||
menus.addItemByPath("Support/Learning/", null, c += 100, plugin);
|
||||
menus.addItemByPath("Support/Get Help/", null, c += 100, plugin);
|
||||
menus.addItemByPath("Support/Get in Touch/", null, c += 100, plugin);
|
||||
|
||||
c = 0;
|
||||
menus.addItemByPath("Support/Learning/Cloud9 Documentation", new ui.item({
|
||||
menus.addItemByPath("Support/~", new ui.divider(), c += 300, plugin);
|
||||
|
||||
menus.addItemByPath("Support/Read Documentation", new ui.item({
|
||||
onclick: function(){
|
||||
window.open("https://docs.c9.io");
|
||||
window.open("https://docs.c9.io/docs");
|
||||
}
|
||||
}), c += 100, plugin);
|
||||
menus.addItemByPath("Support/Learning/YouTube Channel for Cloud9", new ui.item({
|
||||
menus.addItemByPath("Support/Request a Feature", new ui.item({
|
||||
onclick: function() {
|
||||
// draw();
|
||||
window.open('https://community.c9.io/c/feature-requests');
|
||||
}
|
||||
}), c += 100, plugin);
|
||||
menus.addItemByPath("Support/Go To YouTube Channel", new ui.item({
|
||||
onclick: function(){
|
||||
window.open('http://www.youtube.com/user/c9ide/videos?view=pl');
|
||||
}
|
||||
}), c += 100, plugin);
|
||||
|
||||
c = 0;
|
||||
menus.addItemByPath("Support/Get in Touch/Blog", new ui.item({
|
||||
onclick: function(){ window.open('https://blog.c9.io/'); }
|
||||
}), c += 100, plugin);
|
||||
menus.addItemByPath("Support/Get in Touch/Twitter (for Cloud9 Support)", new ui.item({
|
||||
onclick: function(){ window.open('https://twitter.com/C9Support'); }
|
||||
}), c += 100, plugin);
|
||||
menus.addItemByPath("Support/Get in Touch/Twitter (for general Cloud9 tweets)", new ui.item({
|
||||
onclick: function(){ window.open('https://twitter.com/Cloud9IDE'); }
|
||||
}), c += 100, plugin);
|
||||
menus.addItemByPath("Support/Get in Touch/Facebook", new ui.item({
|
||||
onclick: function(){ window.open('https://www.facebook.com/Cloud9IDE'); }
|
||||
}), c += 100, plugin);
|
||||
|
||||
if (c9.hosted || c9.local) {
|
||||
c9.on("state.change", fetchBlog);
|
||||
|
|
|
@ -43,9 +43,9 @@ define(function(require, exports, module) {
|
|||
var plugins = [];
|
||||
|
||||
var ENABLED = c9.location.indexOf("debug=2") > -1;
|
||||
var HASSDK = experimental.addExperiment("sdk", false, "SDK/Load Custom Plugins");;
|
||||
var HASSDK = ENABLED || experimental.addExperiment("sdk", false, "SDK/Load Custom Plugins");
|
||||
|
||||
var reParts = /^(builders|keymaps|modes|outline|runners|snippets|themes)\/(.*)/;
|
||||
var reParts = /^(builders|keymaps|modes|outline|runners|snippets|themes|templates)\/(.*)/;
|
||||
var reModule = /(?:_highlight_rules|_test|_worker|_fold|_behaviou?r)\.js$/;
|
||||
var jsExtRe = /\.js$/;
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@ define(function(require, exports, module) {
|
|||
var plugin = new Plugin("Ajax.org", main.consumes);
|
||||
var emit = plugin.getEmitter();
|
||||
|
||||
var HASSDK = experimental.addExperiment("sdk", false, "SDK/Load Custom Plugins");
|
||||
var DEBUG_MODE = c9.location.indexOf("debug=2") > -1;
|
||||
var HASSDK = DEBUG_MODE || experimental.addExperiment("sdk", false, "SDK/Load Custom Plugins");
|
||||
|
||||
var installing;
|
||||
|
||||
|
|
|
@ -28,8 +28,9 @@ define(function(require, exports, module) {
|
|||
var plugin = new Plugin("Ajax.org", main.consumes);
|
||||
// var emit = plugin.getEmitter();
|
||||
|
||||
var ENABLED = experimental.addExperiment("plugins", false, "SDK/Load Plugins From Workspace");
|
||||
var HASSDK = experimental.addExperiment("sdk", false, "SDK/Load Custom Plugins");
|
||||
var DEBUG_MODE = c9.location.indexOf("debug=2") > -1;
|
||||
var ENABLED = DEBUG_MODE || experimental.addExperiment("plugins", false, "SDK/Load Plugins From Workspace");
|
||||
var HASSDK = DEBUG_MODE || experimental.addExperiment("sdk", false, "SDK/Load Custom Plugins");
|
||||
|
||||
var plugins = options.plugins;
|
||||
var loadFromDisk = options.loadFromDisk
|
||||
|
|
|
@ -31,7 +31,8 @@ define(function(require, exports, module) {
|
|||
var emit = handle.getEmitter();
|
||||
emit.setMaxListeners(1000);
|
||||
|
||||
var HASSDK = experimental.addExperiment("sdk", false, "SDK/Load Custom Plugins");
|
||||
var DEBUG_MODE = c9.location.indexOf("debug=2") > -1;
|
||||
var HASSDK = DEBUG_MODE || experimental.addExperiment("sdk", false, "SDK/Load Custom Plugins");
|
||||
|
||||
function focusOpenPackages(){
|
||||
var pages = tabs.getTabs();
|
||||
|
|
|
@ -35,6 +35,7 @@ define(function(require, exports, module) {
|
|||
ace_tree: "lib/ace_tree/lib/ace_tree",
|
||||
treehugger: "lib/treehugger/lib/treehugger",
|
||||
acorn: "lib/treehugger/lib/acorn",
|
||||
jsonm: "lib/jsonm",
|
||||
tern: "lib/tern",
|
||||
tern_from_ts: "lib/tern_from_ts",
|
||||
ui: "lib/ui",
|
||||
|
@ -60,6 +61,7 @@ define(function(require, exports, module) {
|
|||
"tern",
|
||||
"tern_from_ts",
|
||||
"treehugger",
|
||||
"jsonm",
|
||||
"pivottable",
|
||||
"architect",
|
||||
"source-map",
|
||||
|
|
|
@ -68,10 +68,10 @@ define(function(require, exports, module) {
|
|||
bindKey: {win: "Ctrl-Delete", mac: "Option-Delete"},
|
||||
name: "\u001bd" // "alt-d"
|
||||
}, {
|
||||
bindKey: {win: "Alt-Backspace|Shift-Backspace", mac: "Ctrl-Backspace|Shift-Backspace"},
|
||||
bindKey: {win: "Alt-Backspace", mac: "Ctrl-Backspace"},
|
||||
name: "\u0015" // "ctrl-u"
|
||||
}, {
|
||||
bindKey: {win: "Alt-Delete|Shift-Delete", mac: "Ctrl-Delete|Shift-Delete"},
|
||||
bindKey: {win: "Alt-Delete", mac: "Ctrl-Delete"},
|
||||
name: "\u000b" // "ctrl-k"
|
||||
}, {
|
||||
bindKey: {win: "Ctrl-z", mac: "Cmd-z"},
|
||||
|
|
|
@ -2988,10 +2988,11 @@ String.prototype.trim = function(){
|
|||
* @param {Number} times Number of times to repeat the String concatenation
|
||||
* @type {String}
|
||||
*/
|
||||
String.prototype.repeat = function(times) {
|
||||
return Array(times + 1).join(this);
|
||||
};
|
||||
|
||||
if (!String.prototype.repeat) {
|
||||
String.prototype.repeat = function(times) {
|
||||
return Array(times + 1).join(this);
|
||||
};
|
||||
}
|
||||
/*
|
||||
* Count the number of occurences of substring 'str' inside a string
|
||||
*
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
"use strict";
|
||||
|
||||
var Path = require("path");
|
||||
|
||||
module.exports = function sanitzePreviewPath(req, res, next) {
|
||||
var normalized = Path.normalize(decodeURIComponent(req.params.path));
|
||||
|
||||
// N.B. Path.normalize does not strip away when the path starts with "../"
|
||||
if (normalized)
|
||||
normalized = normalized.replace(/[.]{2}\//g, "") || "/";
|
||||
|
||||
req.params.path = normalized;
|
||||
|
||||
next();
|
||||
};
|
|
@ -0,0 +1,60 @@
|
|||
"use struct";
|
||||
"use server";
|
||||
|
||||
require("c9/inline-mocha")(module);
|
||||
|
||||
var sanitize = require("./sanitize-path-param");
|
||||
var async = require("async");
|
||||
var format = require("util").format;
|
||||
var assert = require("assert");
|
||||
|
||||
describe(__filename, function() {
|
||||
it("should sanitize params", function(done) {
|
||||
|
||||
//https://preview.new-mvhenten.c9.io/mvhenten/demo-project/%2e%2e/foo.txt
|
||||
|
||||
|
||||
var cases = [{
|
||||
path: "%2e%2e/foo.txt",
|
||||
expect: "foo.txt"
|
||||
}, {
|
||||
path: "%2e%2e/%2e%2e/foo.txt",
|
||||
expect: "foo.txt"
|
||||
}, {
|
||||
path: "%2e%2e/%2e%2e/%2e%2e/foo.txt",
|
||||
expect: "foo.txt"
|
||||
}, {
|
||||
path: "foo/bar/%2e%2e/%2e%2e/xoo.txt",
|
||||
expect: "xoo.txt"
|
||||
}, {
|
||||
path: "../foo.txt",
|
||||
expect: "foo.txt"
|
||||
}, {
|
||||
path: "foo/../../foo.txt",
|
||||
expect: "foo.txt"
|
||||
}, {
|
||||
path: "%7E/foo/../../foo.txt",
|
||||
expect: "foo.txt"
|
||||
}, {
|
||||
path: "~/foo.txt",
|
||||
expect: "~/foo.txt"
|
||||
}, {
|
||||
path: "%7E/../foo.txt",
|
||||
expect: "foo.txt"
|
||||
}];
|
||||
|
||||
|
||||
async.each(cases, function(testCase, next) {
|
||||
var mockReq = {
|
||||
params: {
|
||||
path: testCase.path
|
||||
}
|
||||
};
|
||||
|
||||
sanitize(mockReq, null, function() {
|
||||
assert.equal(mockReq.params.path, testCase.expect, format("Expect %s to become %s", testCase.path, testCase.expect));
|
||||
next();
|
||||
});
|
||||
}, done);
|
||||
});
|
||||
});
|
|
@ -21,6 +21,7 @@ define(function(require, exports, module) {
|
|||
var userContent = imports["user-content.redirect"];
|
||||
var getVfsServers = imports["vfs.serverlist"].getServers;
|
||||
|
||||
|
||||
var frontdoor = require("frontdoor");
|
||||
var error = require("http-error");
|
||||
var requestTimeout = require("c9/request_timeout");
|
||||
|
@ -50,6 +51,7 @@ define(function(require, exports, module) {
|
|||
}
|
||||
}, [
|
||||
requestTimeout(15*60*1000),
|
||||
require("./lib/middleware/sanitize-path-param"),
|
||||
handler.getProjectSession(),
|
||||
handler.getRole(db),
|
||||
handler.getProxyUrl(function() {
|
||||
|
|
|
@ -264,9 +264,9 @@ function main(options, imports, register) {
|
|||
"plugins/c9.ide.language.javascript.infer/infer_jumptodef",
|
||||
"plugins/c9.ide.language.javascript.infer/infer_tooltip",
|
||||
"plugins/c9.ide.language.javascript.infer/infer_completer",
|
||||
"plugins/c9.ide.language.python/worker/python_worker",
|
||||
"plugins/c9.ide.language.python/worker/python_jsonalyzer_worker",
|
||||
"plugins/c9.ide.language.python/server/python_jsonalyzer_server_worker",
|
||||
"plugins/c9.ide.language.python/worker/python_linter",
|
||||
"plugins/c9.ide.language.python/worker/python_completer",
|
||||
"plugins/c9.ide.language.python/worker/python_jsonalyzer",
|
||||
"plugins/c9.ide.language.html/html_completer",
|
||||
"plugins/c9.ide.language.css/css_handler",
|
||||
"plugins/c9.ide.language.javascript.tern/worker/tern_worker",
|
||||
|
|
|
@ -183,7 +183,6 @@ function plugin(options, imports, register) {
|
|||
|
||||
api.get("/configs/require_config.js", function(req, res, next) {
|
||||
var config = res.getOptions().requirejsConfig || {};
|
||||
config.waitSeconds = 240;
|
||||
|
||||
res.writeHead(200, {"Content-Type": "application/javascript"});
|
||||
res.end("requirejs.config(" + JSON.stringify(config) + ");");
|
||||
|
@ -212,6 +211,54 @@ function plugin(options, imports, register) {
|
|||
|
||||
api.get("/api.json", {name: "api"}, frontdoor.middleware.describeApi(api));
|
||||
|
||||
api.get("/api/project/:pid/persistent/:apikey", {
|
||||
params: {
|
||||
pid: { type: "number" },
|
||||
apikey: { type: "string" }
|
||||
}
|
||||
}, persistentDataApiMock);
|
||||
api.put("/api/project/:pid/persistent/:apikey", {
|
||||
params: {
|
||||
data: { type: "string", source: "body" },
|
||||
pid: { type: "number" },
|
||||
apikey: { type: "string" },
|
||||
}
|
||||
}, persistentDataApiMock);
|
||||
api.get("/api/user/persistent/:apikey", {
|
||||
params: {
|
||||
apikey: { type: "string" }
|
||||
}
|
||||
}, persistentDataApiMock);
|
||||
api.put("/api/user/persistent/:apikey", {
|
||||
params: {
|
||||
data: { type: "string", source: "body" },
|
||||
apikey: { type: "string" },
|
||||
}
|
||||
}, persistentDataApiMock);
|
||||
|
||||
function persistentDataApiMock(req, res, next) {
|
||||
var name = (req.params.pid || 0) + "-" + req.params.apikey;
|
||||
var data = req.params.data;
|
||||
console.log(name, data)
|
||||
if (/[^\w+=\-]/.test(name))
|
||||
return next(new Error("Invalid apikey"));
|
||||
var path = join(options.installPath, ".c9", "persistent");
|
||||
var method = req.method.toLowerCase()
|
||||
if (method == "get") {
|
||||
res.writeHead(200, {"Content-Type": "application/octet-stream"});
|
||||
var stream = fs.createReadStream(path + "/" + name);
|
||||
stream.pipe(res);
|
||||
} else if (method == "put") {
|
||||
require("mkdirp")(path, function(e) {
|
||||
fs.writeFile(path + "/" + name, data, "", function(err) {
|
||||
if (err) return next(err);
|
||||
res.writeHead(200, {"Content-Type": "application/octet-stream"});
|
||||
res.end("");
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// fake authentication
|
||||
api.authenticate = api.authenticate || function() {
|
||||
return function(req, res, next) {
|
||||
|
|
|
@ -109,6 +109,9 @@
|
|||
if (window.hideLoader)
|
||||
window.hideLoader();
|
||||
}
|
||||
}, function loadError(mod) {
|
||||
if (mod.id === "plugins/c9.ide.clipboard/html5")
|
||||
return alert("Unable to load html5.js.\n\nThis may be caused by a false positive in your virus scanner. Please try reloading with ?packed=1 added to the URL.");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
27
server.js
27
server.js
|
@ -12,6 +12,7 @@ var optimist = require("optimist");
|
|||
var async = require("async");
|
||||
var os = require("os");
|
||||
var urls = require("c9/urls");
|
||||
var child_process = require("child_process");
|
||||
require("c9/setup_paths.js");
|
||||
|
||||
if (process.version.match(/^v0/) && parseFloat(process.version.substr(3)) < 10) {
|
||||
|
@ -26,8 +27,21 @@ var shortcuts = {
|
|||
"dev": ["ide", "preview", "user-content", "vfs", "api", "sapi", "proxy", "redis", "profile", "oldclient", "homepage", "apps-proxy", "-s", "devel"],
|
||||
"onlinedev": ["ide", "preview", "user-content", "vfs", "api", "proxy", "oldclient", "homepage", "apps-proxy", "profile", "-s", "onlinedev"],
|
||||
"beta": ["ide", "preview", "user-content", "vfs", "proxy", "-s", "beta"],
|
||||
"s": ["standalone", "-s", "standalone"]
|
||||
"s": ["standalone", "-s", "standalone"],
|
||||
};
|
||||
shortcuts.localdev = shortcuts.onlinedev.concat([
|
||||
"-s", "beta",
|
||||
"--ide.packed", "false",
|
||||
"--ide.cdn", "false",
|
||||
"--ide.forceDev", "true",
|
||||
"--homepage.cdn", "false",
|
||||
"--helpWithSudo",
|
||||
"--api.port", "8281",
|
||||
"--infra_port", "8282",
|
||||
"--api_url", "http://api.c9.local:8281",
|
||||
"--domains", "c9.local",
|
||||
"--cdn.abbreviateVersion", "true",
|
||||
]);
|
||||
shortcuts.odev = shortcuts.onlinedev; // For backwards compatibility, if you see this in 2016 remove this line
|
||||
var delayLoadConfigs = [
|
||||
// Services that are usually not immediately needed
|
||||
|
@ -69,6 +83,8 @@ function main(argv, config, onLoaded) {
|
|||
.describe("dump", "dump config file as JSON")
|
||||
.describe("domains", "Primary and any secondary top-level domains to use (e.g, c9.io,c9.dev)")
|
||||
.describe("exclude", "Exclude specified service")
|
||||
.describe("include", "Include only specified service")
|
||||
.describe("helpWithSudo", "Ask for sudo password on startup")
|
||||
.default("domains", inContainer && process.env.C9_HOSTNAME || process.env.C9_DOMAINS)
|
||||
.boolean("help")
|
||||
.describe("help", "Show command line options.");
|
||||
|
@ -80,14 +96,23 @@ function main(argv, config, onLoaded) {
|
|||
options.argv.exclude = [options.argv.exclude];
|
||||
|
||||
var expanded = expandShortCuts(configs);
|
||||
|
||||
if (expanded.length > configs.length)
|
||||
return main(expanded.concat(argv.filter(function(arg) {
|
||||
return !shortcuts[arg];
|
||||
})), config, onLoaded);
|
||||
|
||||
if (options.argv.include)
|
||||
expanded = [].concat(options.argv.include);
|
||||
|
||||
var delayed = expanded.filter(function(c) { return delayLoadConfigs.indexOf(c) !== -1 });
|
||||
var notDelayed = expanded.filter(function(c) { return delayLoadConfigs.indexOf(c) === -1 });
|
||||
|
||||
if (options.argv.helpWithSudo)
|
||||
return child_process.execFile("sudo", ["echo -n"], main.bind(null, argv.filter(function(a) {
|
||||
return a !== "--helpWithSudo";
|
||||
}), config, onLoaded));
|
||||
|
||||
startConfigs(notDelayed, function() {
|
||||
startConfigs(delayed, function() {
|
||||
console.log("Cloud9 is up and running");
|
||||
|
|
|
@ -63,7 +63,7 @@ module.exports = function(manifest, installPath) {
|
|||
ideBaseUrl: "http://c9.io",
|
||||
previewUrl: "/preview",
|
||||
dashboardUrl: "https://c9.io/dashboard.html",
|
||||
apiUrl: "https://api.c9.dev",
|
||||
apiUrl: "/api",
|
||||
homeUrl: "/home",
|
||||
collab: false,
|
||||
installed: true,
|
||||
|
@ -94,9 +94,6 @@ module.exports = function(manifest, installPath) {
|
|||
},
|
||||
assumeConnected: true
|
||||
},
|
||||
feedback: {
|
||||
userSnapApiKey: "a83fc136-1bc4-4ab8-8158-e750c30873b5"
|
||||
},
|
||||
support: {
|
||||
userSnapApiKey: "e3d3b232-1c21-4961-b73d-fbc8dc7be1c3"
|
||||
},
|
||||
|
@ -120,12 +117,6 @@ module.exports = function(manifest, installPath) {
|
|||
integrations: {
|
||||
"All": true
|
||||
}
|
||||
},
|
||||
treasureData: {
|
||||
tdWriteKey: "12346",
|
||||
tdDb: "test_db",
|
||||
tdAgentHost: "localhost",
|
||||
tdAgentPort: 24224
|
||||
}
|
||||
},
|
||||
raygun: {
|
||||
|
|
|
@ -12,7 +12,8 @@ modules._resolveFilename = function(request, parent) {
|
|||
// Ensure client extensions can be loaded
|
||||
request = request.replace(/^ext\//, "ext.")
|
||||
.replace(/^core\//, "cloud9.core/www/core/")
|
||||
.replace(/^lib\/chai\//, "chai/");
|
||||
.replace(/^lib\/chai\//, "chai/")
|
||||
.replace(/^lib\/jsonm\//, "jsonm/");
|
||||
// Add the extra paths
|
||||
extraPaths.forEach(function(p) {
|
||||
if (parent.paths.indexOf(p) === -1)
|
||||
|
|
Ładowanie…
Reference in New Issue