Skip to content

Commit 9b5c845

Browse files
Cache feature resolution state to avoid potential O(n^2) work. Features should never change
1 parent cac7293 commit 9b5c845

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

src/object.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ function ReflectionObject(name, options) {
6767
*/
6868
this._features = {};
6969

70+
/**
71+
* Whether or not features have been resolved.
72+
* @type {boolean}
73+
* /
74+
this._featuresResolved = false;
75+
7076
/**
7177
* Parent namespace.
7278
* @type {Namespace|null}
@@ -173,7 +179,6 @@ ReflectionObject.prototype.resolve = function resolve() {
173179
if (this.resolved)
174180
return this;
175181
if (this instanceof Root) {
176-
this._resolveFeaturesRecursive(this._edition);
177182
this.resolved = true;
178183
}
179184
return this;
@@ -194,6 +199,10 @@ ReflectionObject.prototype._resolveFeaturesRecursive = function _resolveFeatures
194199
* @returns {undefined}
195200
*/
196201
ReflectionObject.prototype._resolveFeatures = function _resolveFeatures(edition) {
202+
if (this._featuresResolved) {
203+
return;
204+
}
205+
197206
var defaults = {};
198207

199208
/* istanbul ignore if */
@@ -217,6 +226,7 @@ ReflectionObject.prototype._resolveFeatures = function _resolveFeatures(edition)
217226
throw new Error("Unknown edition: " + edition);
218227
}
219228
this._features = Object.assign(defaults, protoFeatures || {});
229+
this._featuresResolved = true;
220230
return;
221231
}
222232

@@ -238,6 +248,7 @@ ReflectionObject.prototype._resolveFeatures = function _resolveFeatures(edition)
238248
// Sister fields should have the same features as their extensions.
239249
this.extensionField._features = this._features;
240250
}
251+
this._featuresResolved = true;
241252
};
242253

243254
/**

src/root.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ Root.prototype.resolveAll = function resolveAll() {
272272
throw Error("unresolvable extensions: " + this.deferred.map(function(field) {
273273
return "'extend " + field.extend + "' in " + field.parent.fullName;
274274
}).join(", "));
275+
this._resolveFeaturesRecursive(this._edition);
275276
return Namespace.prototype.resolveAll.call(this);
276277
};
277278

0 commit comments

Comments
 (0)