Skip to content

Commit

Permalink
Other: Also check for reserved ids and names in enums
Browse files Browse the repository at this point in the history
  • Loading branch information
dcodeIO committed Nov 27, 2017
1 parent 843d0d5 commit 685adb0
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 18 deletions.
41 changes: 33 additions & 8 deletions src/enum.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ module.exports = Enum;
var ReflectionObject = require("./object");
((Enum.prototype = Object.create(ReflectionObject.prototype)).constructor = Enum).className = "Enum";

var util = require("./util");
var Namespace = require("./namespace"),
util = require("./util");

/**
* Constructs a new enum instance.
Expand Down Expand Up @@ -84,7 +85,7 @@ Enum.prototype.toJSON = function toJSON() {
return util.toObject([
"options" , this.options,
"values" , this.values,
"reserved" , this.reserved
"reserved" , this.reserved && this.reserved.length ? this.reserved : undefined
]);
};

Expand All @@ -97,7 +98,7 @@ Enum.prototype.toJSON = function toJSON() {
* @throws {TypeError} If arguments are invalid
* @throws {Error} If there is already a value with this name or id
*/
Enum.prototype.add = function(name, id, comment) {
Enum.prototype.add = function add(name, id, comment) {
// utilized by the parser but not by .fromJSON

if (!util.isString(name))
Expand All @@ -107,11 +108,17 @@ Enum.prototype.add = function(name, id, comment) {
throw TypeError("id must be an integer");

if (this.values[name] !== undefined)
throw Error("duplicate name");
throw Error("duplicate name '" + name + "' in " + this);

if (this.isReservedId(id))
throw Error("id " + id + " is reserved in " + this);

if (this.isReservedName(name))
throw Error("name '" + name + "' is reserved in " + this);

if (this.valuesById[id] !== undefined) {
if (!(this.options && this.options.allow_alias))
throw Error("duplicate id");
throw Error("duplicate id " + id + " in " + this);
this.values[name] = id;
} else
this.valuesById[this.values[name] = id] = name;
Expand All @@ -127,18 +134,36 @@ Enum.prototype.add = function(name, id, comment) {
* @throws {TypeError} If arguments are invalid
* @throws {Error} If `name` is not a name of this enum
*/
Enum.prototype.remove = function(name) {
Enum.prototype.remove = function remove(name) {

if (!util.isString(name))
throw TypeError("name must be a string");

var val = this.values[name];
if (val === undefined)
throw Error("name does not exist");
if (val == null)
throw Error("name '" + name + "' does not exist in " + this);

delete this.valuesById[val];
delete this.values[name];
delete this.comments[name];

return this;
};

/**
* Tests if the specified id is reserved.
* @param {number} id Id to test
* @returns {boolean} `true` if reserved, otherwise `false`
*/
Enum.prototype.isReservedId = function isReservedId(id) {
return Namespace.isReservedId(this.reserved, id);
};

/**
* Tests if the specified name is reserved.
* @param {string} name Name to test
* @returns {boolean} `true` if reserved, otherwise `false`
*/
Enum.prototype.isReservedName = function isReservedName(name) {
return Namespace.isReservedName(this.reserved, name);
};
28 changes: 28 additions & 0 deletions src/namespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,34 @@ function arrayToJSON(array) {

Namespace.arrayToJSON = arrayToJSON;

/**
* Tests if the specified id is reserved.
* @param {Array.<number[]|string>|undefined} reserved Array of reserved ranges and names
* @param {number} id Id to test
* @returns {boolean} `true` if reserved, otherwise `false`
*/
Namespace.isReservedId = function isReservedId(reserved, id) {
if (reserved)
for (var i = 0; i < reserved.length; ++i)
if (typeof reserved[i] !== "string" && reserved[i][0] <= id && reserved[i][1] >= id)
return true;
return false;
};

/**
* Tests if the specified name is reserved.
* @param {Array.<number[]|string>|undefined} reserved Array of reserved ranges and names
* @param {string} name Name to test
* @returns {boolean} `true` if reserved, otherwise `false`
*/
Namespace.isReservedName = function isReservedName(reserved, name) {
if (reserved)
for (var i = 0; i < reserved.length; ++i)
if (reserved[i] === name)
return true;
return false;
};

/**
* Not an actual constructor. Use {@link Namespace} instead.
* @classdesc Base class of all reflection objects containing nested objects. This is not an actual class but here for the sake of having consistent type definitions.
Expand Down
12 changes: 2 additions & 10 deletions src/type.js
Original file line number Diff line number Diff line change
Expand Up @@ -395,11 +395,7 @@ Type.prototype.remove = function remove(object) {
* @returns {boolean} `true` if reserved, otherwise `false`
*/
Type.prototype.isReservedId = function isReservedId(id) {
if (this.reserved)
for (var i = 0; i < this.reserved.length; ++i)
if (typeof this.reserved[i] !== "string" && this.reserved[i][0] <= id && this.reserved[i][1] >= id)
return true;
return false;
return Namespace.isReservedId(this.reserved, id);
};

/**
Expand All @@ -408,11 +404,7 @@ Type.prototype.isReservedId = function isReservedId(id) {
* @returns {boolean} `true` if reserved, otherwise `false`
*/
Type.prototype.isReservedName = function isReservedName(name) {
if (this.reserved)
for (var i = 0; i < this.reserved.length; ++i)
if (this.reserved[i] === name)
return true;
return false;
return Namespace.isReservedName(this.reserved, name);
};

/**
Expand Down

0 comments on commit 685adb0

Please sign in to comment.