123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- "use strict";
- module.exports = ReflectionObject;
- ReflectionObject.className = "ReflectionObject";
- var util = require("./util");
- var Root; // cyclic
- /**
- * Constructs a new reflection object instance.
- * @classdesc Base class of all reflection objects.
- * @constructor
- * @param {string} name Object name
- * @param {Object.<string,*>} [options] Declared options
- * @abstract
- */
- function ReflectionObject(name, options) {
- if (!util.isString(name))
- throw TypeError("name must be a string");
- if (options && !util.isObject(options))
- throw TypeError("options must be an object");
- /**
- * Options.
- * @type {Object.<string,*>|undefined}
- */
- this.options = options; // toJSON
- /**
- * Parsed Options.
- * @type {Array.<Object.<string,*>>|undefined}
- */
- this.parsedOptions = null;
- /**
- * Unique name within its namespace.
- * @type {string}
- */
- this.name = name;
- /**
- * Parent namespace.
- * @type {Namespace|null}
- */
- this.parent = null;
- /**
- * Whether already resolved or not.
- * @type {boolean}
- */
- this.resolved = false;
- /**
- * Comment text, if any.
- * @type {string|null}
- */
- this.comment = null;
- /**
- * Defining file name.
- * @type {string|null}
- */
- this.filename = null;
- }
- Object.defineProperties(ReflectionObject.prototype, {
- /**
- * Reference to the root namespace.
- * @name ReflectionObject#root
- * @type {Root}
- * @readonly
- */
- root: {
- get: function() {
- var ptr = this;
- while (ptr.parent !== null)
- ptr = ptr.parent;
- return ptr;
- }
- },
- /**
- * Full name including leading dot.
- * @name ReflectionObject#fullName
- * @type {string}
- * @readonly
- */
- fullName: {
- get: function() {
- var path = [ this.name ],
- ptr = this.parent;
- while (ptr) {
- path.unshift(ptr.name);
- ptr = ptr.parent;
- }
- return path.join(".");
- }
- }
- });
- /**
- * Converts this reflection object to its descriptor representation.
- * @returns {Object.<string,*>} Descriptor
- * @abstract
- */
- ReflectionObject.prototype.toJSON = /* istanbul ignore next */ function toJSON() {
- throw Error(); // not implemented, shouldn't happen
- };
- /**
- * Called when this object is added to a parent.
- * @param {ReflectionObject} parent Parent added to
- * @returns {undefined}
- */
- ReflectionObject.prototype.onAdd = function onAdd(parent) {
- if (this.parent && this.parent !== parent)
- this.parent.remove(this);
- this.parent = parent;
- this.resolved = false;
- var root = parent.root;
- if (root instanceof Root)
- root._handleAdd(this);
- };
- /**
- * Called when this object is removed from a parent.
- * @param {ReflectionObject} parent Parent removed from
- * @returns {undefined}
- */
- ReflectionObject.prototype.onRemove = function onRemove(parent) {
- var root = parent.root;
- if (root instanceof Root)
- root._handleRemove(this);
- this.parent = null;
- this.resolved = false;
- };
- /**
- * Resolves this objects type references.
- * @returns {ReflectionObject} `this`
- */
- ReflectionObject.prototype.resolve = function resolve() {
- if (this.resolved)
- return this;
- if (this.root instanceof Root)
- this.resolved = true; // only if part of a root
- return this;
- };
- /**
- * Gets an option value.
- * @param {string} name Option name
- * @returns {*} Option value or `undefined` if not set
- */
- ReflectionObject.prototype.getOption = function getOption(name) {
- if (this.options)
- return this.options[name];
- return undefined;
- };
- /**
- * Sets an option.
- * @param {string} name Option name
- * @param {*} value Option value
- * @param {boolean} [ifNotSet] Sets the option only if it isn't currently set
- * @returns {ReflectionObject} `this`
- */
- ReflectionObject.prototype.setOption = function setOption(name, value, ifNotSet) {
- if (!ifNotSet || !this.options || this.options[name] === undefined)
- (this.options || (this.options = {}))[name] = value;
- return this;
- };
- /**
- * Sets a parsed option.
- * @param {string} name parsed Option name
- * @param {*} value Option value
- * @param {string} propName dot '.' delimited full path of property within the option to set. if undefined\empty, will add a new option with that value
- * @returns {ReflectionObject} `this`
- */
- ReflectionObject.prototype.setParsedOption = function setParsedOption(name, value, propName) {
- if (!this.parsedOptions) {
- this.parsedOptions = [];
- }
- var parsedOptions = this.parsedOptions;
- if (propName) {
- // If setting a sub property of an option then try to merge it
- // with an existing option
- var opt = parsedOptions.find(function (opt) {
- return Object.prototype.hasOwnProperty.call(opt, name);
- });
- if (opt) {
- // If we found an existing option - just merge the property value
- var newValue = opt[name];
- util.setProperty(newValue, propName, value);
- } else {
- // otherwise, create a new option, set it's property and add it to the list
- opt = {};
- opt[name] = util.setProperty({}, propName, value);
- parsedOptions.push(opt);
- }
- } else {
- // Always create a new option when setting the value of the option itself
- var newOpt = {};
- newOpt[name] = value;
- parsedOptions.push(newOpt);
- }
- return this;
- };
- /**
- * Sets multiple options.
- * @param {Object.<string,*>} options Options to set
- * @param {boolean} [ifNotSet] Sets an option only if it isn't currently set
- * @returns {ReflectionObject} `this`
- */
- ReflectionObject.prototype.setOptions = function setOptions(options, ifNotSet) {
- if (options)
- for (var keys = Object.keys(options), i = 0; i < keys.length; ++i)
- this.setOption(keys[i], options[keys[i]], ifNotSet);
- return this;
- };
- /**
- * Converts this instance to its string representation.
- * @returns {string} Class name[, space, full name]
- */
- ReflectionObject.prototype.toString = function toString() {
- var className = this.constructor.className,
- fullName = this.fullName;
- if (fullName.length)
- return className + " " + fullName;
- return className;
- };
- // Sets up cyclic dependencies (called in index-light)
- ReflectionObject._configure = function(Root_) {
- Root = Root_;
- };
|