Bug 1391405: Part 3b - Speed up schema normalization for choices types some more. r?zombie
Like part a, but for `choices` messages rather than error messages.
MozReview-Commit-ID: 7dJ0NL2fUh5
--- a/toolkit/components/extensions/Schemas.jsm
+++ b/toolkit/components/extensions/Schemas.jsm
@@ -401,17 +401,17 @@ class Context {
* If the context has a `currentTarget` value, this is prepended to
* the message to indicate the location of the error.
*
* @param {string|function} errorMessage
* The error message which will be displayed when this is the
* only possible matching schema. If a function is passed, it
* will be evaluated when the error string is first needed, and
* must return a string.
- * @param {string} choicesMessage
+ * @param {string|function} choicesMessage
* The message describing the valid what constitutes a valid
* value for this schema, which will be displayed when multiple
* schema choices are available and none match.
*
* A caller may pass `null` to prevent a choice from being
* added, but this should *only* be done from code processing a
* choices type.
* @returns {object}
@@ -491,29 +491,33 @@ class Context {
let choices = new Set();
this.currentChoices = choices;
this.choicePathIndex = this.path.length;
try {
let result = callback();
- return {result, choices: Array.from(choices)};
+ return {result, choices};
} finally {
this.currentChoices = currentChoices;
this.choicePathIndex = choicePathIndex;
- choices = Array.from(choices);
- if (choices.length == 1) {
- currentChoices.add(choices[0]);
+ if (choices.size == 1) {
+ for (let choice of choices) {
+ currentChoices.add(choice);
+ }
} else if (choices.length) {
- let n = choices.length - 1;
- choices[n] = `or ${choices[n]}`;
-
- this.error(null, `must either [${choices.join(", ")}]`);
+ this.error(null, () => {
+ let array = Array.from(choices, forceString);
+ let n = array.length - 1;
+ array[n] = `or ${array[n]}`;
+
+ return `must either [${array.join(", ")}]`;
+ });
}
}
}
/**
* Appends the given component to the `currentTarget` path to indicate
* that it is being processed, calls the given callback function, and
* then restores the original path.
@@ -1243,20 +1247,21 @@ class ChoiceType extends Type {
error = r;
}
});
if (result) {
return result;
}
- if (choices.length <= 1) {
+ if (choices.size <= 1) {
return error;
}
+ choices = Array.from(choices, forceString);
let n = choices.length - 1;
choices[n] = `or ${choices[n]}`;
let message;
if (typeof value === "object") {
message = () => `Value must either: ${choices.join(", ")}`;
} else {
message = () => `Value ${JSON.stringify(value)} must either: ${choices.join(", ")}`;