Branch data Line data Source code
1 : 25 : /* -*- mode: js; indent-tabs-mode: nil; -*- */
2 : : /* exported bind, copyProperties, copyPublicProperties, countProperties, Class,
3 : : getMetaClass, Interface */
4 : : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
5 : : // SPDX-FileCopyrightText: 2008 litl, LLC
6 : :
7 : : // Utilities that are "meta-language" things like manipulating object props
8 : :
9 : 25 : var {Class, Interface, getMetaClass} = imports._legacy;
10 : :
11 : 1 : function countProperties(obj) {
12 : 1 : let count = 0;
13 [ + + ]: 3 : for (let unusedProperty in obj)
14 : 2 : count += 1;
15 : 1 : return count;
16 : 1 : }
17 : :
18 : 7 : function getPropertyDescriptor(obj, property) {
19 [ - + ]: 7 : if (Object.hasOwn(obj, property))
20 : 7 : return Object.getOwnPropertyDescriptor(obj, property);
21 : 0 : return getPropertyDescriptor(Object.getPrototypeOf(obj), property);
22 : : }
23 : :
24 : 7 : function _copyProperty(source, dest, property) {
25 : 7 : let descriptor = getPropertyDescriptor(source, property);
26 : 7 : Object.defineProperty(dest, property, descriptor);
27 : : }
28 : :
29 : 2 : function copyProperties(source, dest) {
30 [ + + ]: 7 : for (let property in source)
31 : 5 : _copyProperty(source, dest, property);
32 : : }
33 : :
34 : 1 : function copyPublicProperties(source, dest) {
35 [ + + ]: 4 : for (let property in source) {
36 [ - + ][ + + ]: 3 : if (typeof property === 'string' && property.startsWith('_'))
37 : : continue;
38 : : else
39 : 2 : _copyProperty(source, dest, property);
40 : : }
41 : : }
42 : :
43 : : /**
44 : : * Binds obj to callback. Makes it possible to refer to "obj"
45 : : * using this within the callback.
46 : : *
47 : : * @param {object} obj the object to bind
48 : : * @param {Function} callback callback to bind obj in
49 : : * @param {*} bindArguments additional arguments to the callback
50 : : * @returns {Function} a new callback
51 : : */
52 : 5 : function bind(obj, callback, ...bindArguments) {
53 [ + + ]: 5 : if (typeof obj !== 'object') {
54 : 2 : throw new Error(`first argument to Lang.bind() must be an object, not ${
55 : 1 : typeof obj}`);
56 : : }
57 : :
58 [ + + ]: 4 : if (typeof callback !== 'function') {
59 : 2 : throw new Error(`second argument to Lang.bind() must be a function, not ${
60 : 1 : typeof callback}`);
61 : : }
62 : :
63 : : // Use ES5 Function.prototype.bind, but only if not passing any bindArguments,
64 : : // because ES5 has them at the beginning, not at the end
65 [ + + ]: 3 : if (arguments.length === 2)
66 : 1 : return callback.bind(obj);
67 : :
68 : 2 : let me = obj;
69 : 4 : return function (...args) {
70 : 2 : args = args.concat(bindArguments);
71 : 2 : return callback.apply(me, args);
72 : : };
73 : 3 : }
|