aboutsummaryrefslogtreecommitdiff
path: root/node_modules/concordance/lib/describe.js
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-08-14 05:01:11 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-08-14 05:02:09 +0200
commit363723fc84f7b8477592e0105aeb331ec9a017af (patch)
tree29f92724f34131bac64d6a318dd7e30612e631c7 /node_modules/concordance/lib/describe.js
parent5634e77ad96bfe1818f6b6ee70b7379652e5487f (diff)
node_modules
Diffstat (limited to 'node_modules/concordance/lib/describe.js')
-rw-r--r--node_modules/concordance/lib/describe.js170
1 files changed, 170 insertions, 0 deletions
diff --git a/node_modules/concordance/lib/describe.js b/node_modules/concordance/lib/describe.js
new file mode 100644
index 000000000..a8aa94572
--- /dev/null
+++ b/node_modules/concordance/lib/describe.js
@@ -0,0 +1,170 @@
+'use strict'
+
+const argumentsValue = require('./complexValues/arguments')
+const arrayBufferValue = require('./complexValues/arrayBuffer')
+const boxedValue = require('./complexValues/boxed')
+const dataViewValue = require('./complexValues/dataView')
+const dateValue = require('./complexValues/date')
+const errorValue = require('./complexValues/error')
+const functionValue = require('./complexValues/function')
+const globalValue = require('./complexValues/global')
+const mapValue = require('./complexValues/map')
+const objectValue = require('./complexValues/object')
+const promiseValue = require('./complexValues/promise')
+const regexpValue = require('./complexValues/regexp')
+const setValue = require('./complexValues/set')
+const typedArrayValue = require('./complexValues/typedArray')
+
+const itemDescriptor = require('./metaDescriptors/item')
+const mapEntryDescriptor = require('./metaDescriptors/mapEntry')
+const propertyDescriptor = require('./metaDescriptors/property')
+
+const booleanValue = require('./primitiveValues/boolean')
+const nullValue = require('./primitiveValues/null')
+const numberValue = require('./primitiveValues/number')
+const stringValue = require('./primitiveValues/string')
+const symbolValue = require('./primitiveValues/symbol')
+const undefinedValue = require('./primitiveValues/undefined')
+
+const getCtor = require('./getCtor')
+const getStringTag = require('./getStringTag')
+const pluginRegistry = require('./pluginRegistry')
+const Registry = require('./Registry')
+
+const SpecializedComplexes = new Map([
+ ['Arguments', argumentsValue.describe],
+ ['ArrayBuffer', arrayBufferValue.describe],
+ ['DataView', dataViewValue.describe],
+ ['Date', dateValue.describe],
+ ['Error', errorValue.describe],
+ ['Float32Array', typedArrayValue.describe],
+ ['Float64Array', typedArrayValue.describe],
+ ['Function', functionValue.describe],
+ ['GeneratorFunction', functionValue.describe],
+ ['global', globalValue.describe],
+ ['Int16Array', typedArrayValue.describe],
+ ['Int32Array', typedArrayValue.describe],
+ ['Int8Array', typedArrayValue.describe],
+ ['Map', mapValue.describe],
+ ['Promise', promiseValue.describe],
+ ['RegExp', regexpValue.describe],
+ ['Set', setValue.describe],
+ ['Uint16Array', typedArrayValue.describe],
+ ['Uint32Array', typedArrayValue.describe],
+ ['Uint8Array', typedArrayValue.describe],
+ ['Uint8ClampedArray', typedArrayValue.describe]
+])
+
+function describePrimitive (value) {
+ if (value === null) return nullValue.describe()
+ if (value === undefined) return undefinedValue.describe()
+ if (value === true || value === false) return booleanValue.describe(value)
+
+ const type = typeof value
+ if (type === 'number') return numberValue.describe(value)
+ if (type === 'string') return stringValue.describe(value)
+ if (type === 'symbol') return symbolValue.describe(value)
+
+ return null
+}
+
+function unboxComplex (tag, complex) {
+ // Try to unbox by calling `valueOf()`. `describePrimitive()` will return
+ // `null` if the resulting value is not a primitive, in which case it's
+ // ignored.
+ if (typeof complex.valueOf === 'function') {
+ const value = complex.valueOf()
+ if (value !== complex) return describePrimitive(value)
+ }
+
+ return null
+}
+
+function registerPlugins (plugins) {
+ if (!Array.isArray(plugins) || plugins.length === 0) return () => null
+
+ const tryFns = pluginRegistry.getTryDescribeValues(plugins)
+ return (value, stringTag, ctor) => {
+ for (const tryDescribeValue of tryFns) {
+ const describeValue = tryDescribeValue(value, stringTag, ctor)
+ if (describeValue) return describeValue
+ }
+
+ return null
+ }
+}
+
+function describeComplex (value, registry, tryPlugins, describeAny, describeItem, describeMapEntry, describeProperty) {
+ if (registry.has(value)) return registry.get(value)
+
+ const stringTag = getStringTag(value)
+ const ctor = getCtor(stringTag, value)
+ const pointer = registry.alloc(value)
+
+ let unboxed
+ let describeValue = tryPlugins(value, stringTag, ctor)
+ if (describeValue === null) {
+ if (SpecializedComplexes.has(stringTag)) {
+ describeValue = SpecializedComplexes.get(stringTag)
+ } else {
+ unboxed = unboxComplex(stringTag, value)
+ if (unboxed !== null) {
+ describeValue = boxedValue.describe
+ } else {
+ describeValue = objectValue.describe
+ }
+ }
+ }
+
+ const descriptor = describeValue({
+ ctor,
+ describeAny,
+ describeItem,
+ describeMapEntry,
+ describeProperty,
+ pointer: pointer.index,
+ stringTag,
+ unboxed,
+ value
+ })
+ pointer.descriptor = descriptor
+ return descriptor
+}
+
+function describe (value, options) {
+ const primitive = describePrimitive(value)
+ if (primitive !== null) return primitive
+
+ const registry = new Registry()
+ const tryPlugins = registerPlugins(options && options.plugins)
+ const curriedComplex = c => {
+ return describeComplex(c, registry, tryPlugins, describeAny, describeItem, describeMapEntry, describeProperty)
+ }
+
+ const describeAny = any => {
+ const descriptor = describePrimitive(any)
+ return descriptor !== null
+ ? descriptor
+ : curriedComplex(any)
+ }
+
+ const describeItem = (index, valueDescriptor) => {
+ return valueDescriptor.isPrimitive === true
+ ? itemDescriptor.describePrimitive(index, valueDescriptor)
+ : itemDescriptor.describeComplex(index, valueDescriptor)
+ }
+
+ const describeMapEntry = (keyDescriptor, valueDescriptor) => {
+ return mapEntryDescriptor.describe(keyDescriptor, valueDescriptor)
+ }
+
+ const describeProperty = (key, valueDescriptor) => {
+ const keyDescriptor = describePrimitive(key)
+ return valueDescriptor.isPrimitive === true
+ ? propertyDescriptor.describePrimitive(keyDescriptor, valueDescriptor)
+ : propertyDescriptor.describeComplex(keyDescriptor, valueDescriptor)
+ }
+
+ return curriedComplex(value)
+}
+module.exports = describe