Skip to content

Commit 685adb0

Browse files
committed
Other: Also check for reserved ids and names in enums
1 parent 843d0d5 commit 685adb0

File tree

3 files changed

+63
-18
lines changed

3 files changed

+63
-18
lines changed

src/enum.js

+33-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ module.exports = Enum;
55
var ReflectionObject = require("./object");
66
((Enum.prototype = Object.create(ReflectionObject.prototype)).constructor = Enum).className = "Enum";
77

8-
var util = require("./util");
8+
var Namespace = require("./namespace"),
9+
util = require("./util");
910

1011
/**
1112
* Constructs a new enum instance.
@@ -84,7 +85,7 @@ Enum.prototype.toJSON = function toJSON() {
8485
return util.toObject([
8586
"options" , this.options,
8687
"values" , this.values,
87-
"reserved" , this.reserved
88+
"reserved" , this.reserved && this.reserved.length ? this.reserved : undefined
8889
]);
8990
};
9091

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

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

109110
if (this.values[name] !== undefined)
110-
throw Error("duplicate name");
111+
throw Error("duplicate name '" + name + "' in " + this);
112+
113+
if (this.isReservedId(id))
114+
throw Error("id " + id + " is reserved in " + this);
115+
116+
if (this.isReservedName(name))
117+
throw Error("name '" + name + "' is reserved in " + this);
111118

112119
if (this.valuesById[id] !== undefined) {
113120
if (!(this.options && this.options.allow_alias))
114-
throw Error("duplicate id");
121+
throw Error("duplicate id " + id + " in " + this);
115122
this.values[name] = id;
116123
} else
117124
this.valuesById[this.values[name] = id] = name;
@@ -127,18 +134,36 @@ Enum.prototype.add = function(name, id, comment) {
127134
* @throws {TypeError} If arguments are invalid
128135
* @throws {Error} If `name` is not a name of this enum
129136
*/
130-
Enum.prototype.remove = function(name) {
137+
Enum.prototype.remove = function remove(name) {
131138

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

135142
var val = this.values[name];
136-
if (val === undefined)
137-
throw Error("name does not exist");
143+
if (val == null)
144+
throw Error("name '" + name + "' does not exist in " + this);
138145

139146
delete this.valuesById[val];
140147
delete this.values[name];
141148
delete this.comments[name];
142149

143150
return this;
144151
};
152+
153+
/**
154+
* Tests if the specified id is reserved.
155+
* @param {number} id Id to test
156+
* @returns {boolean} `true` if reserved, otherwise `false`
157+
*/
158+
Enum.prototype.isReservedId = function isReservedId(id) {
159+
return Namespace.isReservedId(this.reserved, id);
160+
};
161+
162+
/**
163+
* Tests if the specified name is reserved.
164+
* @param {string} name Name to test
165+
* @returns {boolean} `true` if reserved, otherwise `false`
166+
*/
167+
Enum.prototype.isReservedName = function isReservedName(name) {
168+
return Namespace.isReservedName(this.reserved, name);
169+
};

src/namespace.js

+28
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,34 @@ function arrayToJSON(array) {
5252

5353
Namespace.arrayToJSON = arrayToJSON;
5454

55+
/**
56+
* Tests if the specified id is reserved.
57+
* @param {Array.<number[]|string>|undefined} reserved Array of reserved ranges and names
58+
* @param {number} id Id to test
59+
* @returns {boolean} `true` if reserved, otherwise `false`
60+
*/
61+
Namespace.isReservedId = function isReservedId(reserved, id) {
62+
if (reserved)
63+
for (var i = 0; i < reserved.length; ++i)
64+
if (typeof reserved[i] !== "string" && reserved[i][0] <= id && reserved[i][1] >= id)
65+
return true;
66+
return false;
67+
};
68+
69+
/**
70+
* Tests if the specified name is reserved.
71+
* @param {Array.<number[]|string>|undefined} reserved Array of reserved ranges and names
72+
* @param {string} name Name to test
73+
* @returns {boolean} `true` if reserved, otherwise `false`
74+
*/
75+
Namespace.isReservedName = function isReservedName(reserved, name) {
76+
if (reserved)
77+
for (var i = 0; i < reserved.length; ++i)
78+
if (reserved[i] === name)
79+
return true;
80+
return false;
81+
};
82+
5583
/**
5684
* Not an actual constructor. Use {@link Namespace} instead.
5785
* @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.

src/type.js

+2-10
Original file line numberDiff line numberDiff line change
@@ -395,11 +395,7 @@ Type.prototype.remove = function remove(object) {
395395
* @returns {boolean} `true` if reserved, otherwise `false`
396396
*/
397397
Type.prototype.isReservedId = function isReservedId(id) {
398-
if (this.reserved)
399-
for (var i = 0; i < this.reserved.length; ++i)
400-
if (typeof this.reserved[i] !== "string" && this.reserved[i][0] <= id && this.reserved[i][1] >= id)
401-
return true;
402-
return false;
398+
return Namespace.isReservedId(this.reserved, id);
403399
};
404400

405401
/**
@@ -408,11 +404,7 @@ Type.prototype.isReservedId = function isReservedId(id) {
408404
* @returns {boolean} `true` if reserved, otherwise `false`
409405
*/
410406
Type.prototype.isReservedName = function isReservedName(name) {
411-
if (this.reserved)
412-
for (var i = 0; i < this.reserved.length; ++i)
413-
if (this.reserved[i] === name)
414-
return true;
415-
return false;
407+
return Namespace.isReservedName(this.reserved, name);
416408
};
417409

418410
/**

0 commit comments

Comments
 (0)