Permalink
Cannot retrieve contributors at this time
71 lines (57 sloc)
2.83 KB
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
codeql-action/node_modules/mimic-fn/index.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const copyProperty = (to, from, property, ignoreNonConfigurable) => { | |
// `Function#length` should reflect the parameters of `to` not `from` since we keep its body. | |
// `Function#prototype` is non-writable and non-configurable so can never be modified. | |
if (property === 'length' || property === 'prototype') { | |
return; | |
} | |
// `Function#arguments` and `Function#caller` should not be copied. They were reported to be present in `Reflect.ownKeys` for some devices in React Native (#41), so we explicitly ignore them here. | |
if (property === 'arguments' || property === 'caller') { | |
return; | |
} | |
const toDescriptor = Object.getOwnPropertyDescriptor(to, property); | |
const fromDescriptor = Object.getOwnPropertyDescriptor(from, property); | |
if (!canCopyProperty(toDescriptor, fromDescriptor) && ignoreNonConfigurable) { | |
return; | |
} | |
Object.defineProperty(to, property, fromDescriptor); | |
}; | |
// `Object.defineProperty()` throws if the property exists, is not configurable and either: | |
// - one its descriptors is changed | |
// - it is non-writable and its value is changed | |
const canCopyProperty = function (toDescriptor, fromDescriptor) { | |
return toDescriptor === undefined || toDescriptor.configurable || ( | |
toDescriptor.writable === fromDescriptor.writable && | |
toDescriptor.enumerable === fromDescriptor.enumerable && | |
toDescriptor.configurable === fromDescriptor.configurable && | |
(toDescriptor.writable || toDescriptor.value === fromDescriptor.value) | |
); | |
}; | |
const changePrototype = (to, from) => { | |
const fromPrototype = Object.getPrototypeOf(from); | |
if (fromPrototype === Object.getPrototypeOf(to)) { | |
return; | |
} | |
Object.setPrototypeOf(to, fromPrototype); | |
}; | |
const wrappedToString = (withName, fromBody) => `/* Wrapped ${withName}*/\n${fromBody}`; | |
const toStringDescriptor = Object.getOwnPropertyDescriptor(Function.prototype, 'toString'); | |
const toStringName = Object.getOwnPropertyDescriptor(Function.prototype.toString, 'name'); | |
// We call `from.toString()` early (not lazily) to ensure `from` can be garbage collected. | |
// We use `bind()` instead of a closure for the same reason. | |
// Calling `from.toString()` early also allows caching it in case `to.toString()` is called several times. | |
const changeToString = (to, from, name) => { | |
const withName = name === '' ? '' : `with ${name.trim()}() `; | |
const newToString = wrappedToString.bind(null, withName, from.toString()); | |
// Ensure `to.toString.toString` is non-enumerable and has the same `same` | |
Object.defineProperty(newToString, 'name', toStringName); | |
Object.defineProperty(to, 'toString', {...toStringDescriptor, value: newToString}); | |
}; | |
export default function mimicFunction(to, from, {ignoreNonConfigurable = false} = {}) { | |
const {name} = to; | |
for (const property of Reflect.ownKeys(from)) { | |
copyProperty(to, from, property, ignoreNonConfigurable); | |
} | |
changePrototype(to, from); | |
changeToString(to, from, name); | |
return to; | |
} |