1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-20 12:27:58 +01:00

Deal with some duplicated code, plus some collateral optimization.

This commit is contained in:
Kris Maglione
2010-10-17 22:43:30 -04:00
parent f2242c3567
commit 1e3ce10290
2 changed files with 244 additions and 234 deletions

View File

@@ -258,6 +258,31 @@ const Command = Class("Command", {
optionMap: Class.memoize(function () array(this.options) optionMap: Class.memoize(function () array(this.options)
.map(function (opt) opt.names.map(function (name) [name, opt])) .map(function (opt) opt.names.map(function (name) [name, opt]))
.flatten.toObject()), .flatten.toObject()),
newArgs: function () {
let res = [];
res.__proto__ = this.argsPrototype;
return res;
},
argsPrototype: Class.memoize(function () update([],
array([opt, opt.default] for (opt in values(this.options)) if (set.has(opt, "default")))
.toObject(),
{
__iterator__: function () array.iterItems(this),
command: this,
get literalArg() this.command.literal != null && this[this.command.literal] || "",
// TODO: string: Class.memoize(function () { ... }),
verify: function verify() {
if (this.argCount) {
dactyl.assert((this.length > 0 || !/^[1+]$/.test(this.command.argCount)) &&
(this.literal == null || !/[1+]/.test(this.command.argCount) || /\S/.test(this.literalArg || "")),
"E471: Argument required");
dactyl.assert((this.length == 0 || this.command.argCount !== "0") &&
(this.length <= 1 || !/^[01?]$/.test(this.command.argCount)),
"E488: Trailing characters");
}
}
})),
/** /**
* @property {boolean|function(args)} When true, invocations of this * @property {boolean|function(args)} When true, invocations of this
* command may contain private data which should be purged from * command may contain private data which should be purged from
@@ -355,35 +380,26 @@ const ex = {
let cmd = commands.get(meth); let cmd = commands.get(meth);
dactyl.assert(cmd, "No such command"); dactyl.assert(cmd, "No such command");
let res = cmd.newArgs();
if (isObject(args[0])) if (isObject(args[0]))
for (let [k, v] in Iterator(args.shift())) for (let [k, v] in Iterator(args.shift()))
if (k == "!") if (k == "!")
args.bang = v; res.bang = v;
else if (k == "#") else if (k == "#")
args.count = v; res.count = v;
else { else {
let opt = cmd.optionMap["-" + k]; let opt = cmd.optionMap["-" + k];
let val = opt.type && opt.type.parse(v); let val = opt.type && opt.type.parse(v);
dactyl.assert(val != null && (typeof val !== "number" || !isNaN(val)), dactyl.assert(val != null && (typeof val !== "number" || !isNaN(val)),
"No such option: " + k); "No such option: " + k);
args[opt.names[0]] = val; res[opt.names[0]] = val;
} }
if (cmd.literal != null) for (let [i, val] in array.iterItems(args))
args.literalArg = args[cmd.literal]; res[i] = String(val);
// FIXME: Duplicated in parseArgs. res.verify();
dactyl.assert((args.length > 0 || !/^[1+]$/.test(this.argCount)) && return cmd.execute(res);
(this.literal == null || !/[1+]/.test(this.argCount) || /\S/.test(args.literalArg || "")),
"E471: Argument required");
// This logic eludes me... --Kris
dactyl.assert((args.length == 0 || this.argCount !== "0") &&
(args.length <= 1 || !/^[01?]$/.test(this.argCount)),
"E488: Trailing characters");
// TODO: memoize(args, "string", function () { ... });
return cmd.execute(args);
} }
}; };
@@ -683,6 +699,7 @@ const Commands = Module("commands", {
* @returns {Args} * @returns {Args}
*/ */
parseArgs: function (str, params) { parseArgs: function (str, params) {
try {
function getNextArg(str) { function getNextArg(str) {
if (str.substr(0, 2) === "<<" && hereDoc) { if (str.substr(0, 2) === "<<" && hereDoc) {
let arg = /^<<(\S*)/.exec(str)[1]; let arg = /^<<(\S*)/.exec(str)[1];
@@ -707,10 +724,8 @@ const Commands = Module("commands", {
if (!argCount) if (!argCount)
argCount = "*"; argCount = "*";
var args = []; // parsed options var args = (params.newArgs || Array).call(params); // parsed options
args.__iterator__ = function () array.iterItems(this);
args.string = str; // for access to the unparsed string args.string = str; // for access to the unparsed string
args.literalArg = "";
// FIXME! // FIXME!
for (let [k, v] in Iterator(extra || [])) for (let [k, v] in Iterator(extra || []))
@@ -873,7 +888,6 @@ const Commands = Module("commands", {
sub = arg + sub.substr(count); sub = arg + sub.substr(count);
} }
args.literalArg = sub;
args.push(sub); args.push(sub);
args.quote = null; args.quote = null;
break; break;
@@ -923,21 +937,15 @@ const Commands = Module("commands", {
complete.completions = completeOpts; complete.completions = completeOpts;
} }
// check for correct number of arguments if (args.verify)
if (args.length == 0 && /^[1+]$/.test(argCount) || args.verify();
literal != null && /[1+]/.test(argCount) && !/\S/.test(args.literalArg || "")) {
if (!complete)
fail("E471: Argument required");
}
else if (args.length == 1 && (argCount == "0") ||
args.length > 1 && /^[01?]$/.test(argCount))
fail("E488: Trailing characters");
for (let opt in values(options))
if (set.has(opt, "default") && args[opt.names[0]] === undefined)
args[opt.names[0]] = opt.default;
return args; return args;
}
catch (e if complete && e instanceof FailedAssertion) {
complete.message = e;
return args;
}
}, },
/** /**

View File

@@ -528,6 +528,8 @@ function memoize(obj, key, getter) {
obj.__defineGetter__(key, function replace() ( obj.__defineGetter__(key, function replace() (
Class.replaceProperty(this.instance || this, key, null), Class.replaceProperty(this.instance || this, key, null),
Class.replaceProperty(this.instance || this, key, getter.call(this, key)))); Class.replaceProperty(this.instance || this, key, getter.call(this, key))));
obj.__defineSetter__(key, function replace(val)
Class.replaceProperty(this.instance || this, key, val));
} }
/** /**