diff --git a/lib/dereference.js b/lib/dereference.js index 35eb4196..0a4c919a 100644 --- a/lib/dereference.js +++ b/lib/dereference.js @@ -16,7 +16,7 @@ module.exports = dereference; */ function dereference (parser, options) { // console.log('Dereferencing $ref pointers in %s', parser.$refs._root$Ref.path); - let dereferenced = crawl(parser.schema, parser.$refs._root$Ref.path, "#", [], [], {}, parser.$refs, options); + let dereferenced = crawl(parser.schema, parser.$refs._root$Ref.path, "#", new Set(), new Set(), new Map(), parser.$refs, options); parser.$refs.circular = dereferenced.circular; parser.schema = dereferenced.value; } @@ -27,9 +27,9 @@ function dereference (parser, options) { * @param {*} obj - The value to crawl. If it's not an object or array, it will be ignored. * @param {string} path - The full path of `obj`, possibly with a JSON Pointer in the hash * @param {string} pathFromRoot - The path of `obj` from the schema root - * @param {object[]} parents - An array of the parent objects that have already been dereferenced - * @param {object[]} processedObjects - An array of all the objects that have already been processed - * @param {object} dereferencedCache - An map of all the dereferenced objects + * @param {Set} parents - An array of the parent objects that have already been dereferenced + * @param {Set} processedObjects - An array of all the objects that have already been processed + * @param {Map} dereferencedCache - An map of all the dereferenced objects * @param {$Refs} $refs * @param {$RefParserOptions} options * @returns {{value: object, circular: boolean}} @@ -41,10 +41,10 @@ function crawl (obj, path, pathFromRoot, parents, processedObjects, dereferenced circular: false }; - if (options.dereference.circular === "ignore" || processedObjects.indexOf(obj) === -1) { + if (options.dereference.circular === "ignore" || !processedObjects.has(obj)) { if (obj && typeof obj === "object" && !ArrayBuffer.isView(obj)) { - parents.push(obj); - processedObjects.push(obj); + parents.add(obj); + processedObjects.add(obj); if ($Ref.isAllowed$Ref(obj, options)) { dereferenced = dereference$Ref(obj, path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options); @@ -52,7 +52,7 @@ function crawl (obj, path, pathFromRoot, parents, processedObjects, dereferenced result.value = dereferenced.value; } else { - for (let key of Object.keys(obj)) { + for (const key of Object.keys(obj)) { let keyPath = Pointer.join(path, key); let keyPathFromRoot = Pointer.join(pathFromRoot, key); let value = obj[key]; @@ -67,7 +67,7 @@ function crawl (obj, path, pathFromRoot, parents, processedObjects, dereferenced } } else { - if (parents.indexOf(value) === -1) { + if (!parents.has(value)) { dereferenced = crawl(value, keyPath, keyPathFromRoot, parents, processedObjects, dereferencedCache, $refs, options); circular = dereferenced.circular; // Avoid pointless mutations; breaks frozen objects to no profit @@ -85,7 +85,7 @@ function crawl (obj, path, pathFromRoot, parents, processedObjects, dereferenced } } - parents.pop(); + parents.delete(obj); } } @@ -98,9 +98,9 @@ function crawl (obj, path, pathFromRoot, parents, processedObjects, dereferenced * @param {{$ref: string}} $ref - The JSON Reference to resolve * @param {string} path - The full path of `$ref`, possibly with a JSON Pointer in the hash * @param {string} pathFromRoot - The path of `$ref` from the schema root - * @param {object[]} parents - An array of the parent objects that have already been dereferenced - * @param {object[]} processedObjects - An array of all the objects that have already been dereferenced - * @param {object} dereferencedCache - An map of all the dereferenced objects + * @param {Set} parents - An array of the parent objects that have already been dereferenced + * @param {Set} processedObjects - An array of all the objects that have already been dereferenced + * @param {Map} dereferencedCache - An map of all the dereferenced objects * @param {$Refs} $refs * @param {$RefParserOptions} options * @returns {{value: object, circular: boolean}} @@ -110,9 +110,8 @@ function dereference$Ref ($ref, path, pathFromRoot, parents, processedObjects, d let $refPath = url.resolve(path, $ref.$ref); - if (dereferencedCache[$refPath]) { - const cache = dereferencedCache[$refPath]; - + const cache = dereferencedCache.get($refPath); + if (cache) { const refKeys = Object.keys($ref); if (refKeys.length > 1) { const extraKeys = {}; @@ -142,7 +141,7 @@ function dereference$Ref ($ref, path, pathFromRoot, parents, processedObjects, d // Check for circular references let directCircular = pointer.circular; - let circular = directCircular || parents.indexOf(pointer.value) !== -1; + let circular = directCircular || parents.has(pointer.value); circular && foundCircularReference(path, $refs, options); // Dereference the JSON reference @@ -175,7 +174,7 @@ function dereference$Ref ($ref, path, pathFromRoot, parents, processedObjects, d // only cache if no extra properties than $ref if (Object.keys($ref).length === 1) { - dereferencedCache[$refPath] = dereferencedObject; + dereferencedCache.set($refPath, dereferencedObject); } return dereferencedObject;