LCOV - code coverage report
Current view: top level - modules/core - _common.js (source / functions) Coverage Total Hit
Test: gjs- Code Coverage Lines: 95.1 % 82 78
Test Date: 2024-04-20 17:42:51 Functions: 100.0 % 10 10
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 88.3 % 60 53

             Branch data     Line data    Source code
       1                 :          47 : // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
       2                 :             : 
       3                 :             : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
       4                 :             : // SPDX-FileCopyrightText: 2020 Philip Chimento <philip.chimento@gmail.com>
       5                 :             : 
       6                 :             : /* exported _checkAccessors, _createBuilderConnectFunc, _createClosure,
       7                 :             : _registerType */
       8                 :             : 
       9                 :             : // This is a helper module in which to put code that is common between the
      10                 :             : // legacy GObject.Class system and the new GObject.registerClass system.
      11                 :             : 
      12                 :          47 : var _registerType = Symbol('GObject register type hook');
      13                 :             : 
      14                 :          33 : function _generateAccessors(pspec, propdesc, GObject) {
      15                 :          33 :     const {name, flags} = pspec;
      16                 :          33 :     const readable = flags & GObject.ParamFlags.READABLE;
      17                 :          33 :     const writable = flags & GObject.ParamFlags.WRITABLE;
      18                 :             : 
      19         [ +  + ]:          33 :     if (!propdesc) {
      20                 :          30 :         propdesc = {
      21                 :          30 :             configurable: true,
      22                 :          30 :             enumerable: true,
      23                 :             :         };
      24                 :             :     }
      25                 :             : 
      26 [ +  + ][ +  + ]:          33 :     if (readable && writable) {
      27 [ +  + ][ +  + ]:          18 :         if (!propdesc.get && !propdesc.set) {
      28                 :          15 :             const privateName = Symbol(`__autogeneratedAccessor__${name}`);
      29                 :          15 :             const defaultValue = pspec.get_default_value();
      30                 :          15 :             propdesc.get = function () {
      31         [ +  + ]:          58 :                 if (!(privateName in this))
      32                 :          10 :                     this[privateName] = defaultValue;
      33                 :          58 :                 return this[privateName];
      34                 :             :             };
      35                 :          15 :             propdesc.set = function (value) {
      36         [ +  + ]:          61 :                 if (value !== this[privateName]) {
      37                 :          59 :                     this[privateName] = value;
      38                 :          59 :                     this.notify(name);
      39                 :             :                 }
      40                 :             :             };
      41         [ +  + ]:           3 :         } else if (!propdesc.get) {
      42                 :           1 :             propdesc.get = function () {
      43                 :           1 :                 throw new Error(`setter defined without getter for property ${name}`);
      44                 :             :             };
      45         [ -  + ]:           2 :         } else if (!propdesc.set) {
      46                 :           2 :             propdesc.set = function () {
      47                 :           1 :                 throw new Error(`getter defined without setter for property ${name}`);
      48                 :             :             };
      49                 :             :         }
      50 [ +  + ][ +  + ]:          15 :     } else if (readable && !propdesc.get) {
      51                 :          14 :         propdesc.get = function () {
      52                 :           1 :             throw new Error(`missing getter for read-only property ${name}`);
      53                 :             :         };
      54 [ -  + ][ -  + ]:           1 :     } else if (writable && !propdesc.set) {
      55                 :           1 :         propdesc.set = function () {
      56                 :           1 :             throw new Error(`missing setter for write-only property ${name}`);
      57                 :             :         };
      58                 :             :     }
      59                 :             : 
      60                 :          33 :     return propdesc;
      61                 :          33 : }
      62                 :             : 
      63                 :          66 : function _checkAccessors(proto, pspec, GObject) {
      64                 :          66 :     const {name, flags} = pspec;
      65         [ +  + ]:          66 :     if (flags & GObject.ParamFlags.CONSTRUCT_ONLY)
      66                 :          12 :         return;
      67                 :             : 
      68                 :          54 :     const underscoreName = name.replace(/-/g, '_');
      69                 :          79 :     const camelName = name.replace(/-([a-z])/g, match => match[1].toUpperCase());
      70                 :          54 :     let propdesc = Object.getOwnPropertyDescriptor(proto, name);
      71                 :          54 :     let dashPropdesc = propdesc, underscorePropdesc, camelPropdesc;
      72                 :          54 :     const nameIsCompound = name.includes('-');
      73         [ +  + ]:          54 :     if (nameIsCompound) {
      74                 :          24 :         underscorePropdesc = Object.getOwnPropertyDescriptor(proto, underscoreName);
      75                 :          24 :         camelPropdesc = Object.getOwnPropertyDescriptor(proto, camelName);
      76         [ +  + ]:          24 :         if (!propdesc)
      77                 :          23 :             propdesc = underscorePropdesc;
      78         [ +  + ]:          24 :         if (!propdesc)
      79                 :          16 :             propdesc = camelPropdesc;
      80                 :             :     }
      81                 :             : 
      82                 :          54 :     const readable = flags & GObject.ParamFlags.READABLE;
      83                 :          54 :     const writable = flags & GObject.ParamFlags.WRITABLE;
      84 [ +  + ][ -  + ]:          54 :     if (!propdesc || (readable && !propdesc.get) || (writable && !propdesc.set))
         [ +  + ][ +  + ]
                 [ +  + ]
      85                 :          33 :         propdesc = _generateAccessors(pspec, propdesc, GObject);
      86                 :             : 
      87         [ +  + ]:          54 :     if (!dashPropdesc)
      88                 :          40 :         Object.defineProperty(proto, name, propdesc);
      89         [ +  + ]:          54 :     if (nameIsCompound) {
      90         [ +  + ]:          24 :         if (!underscorePropdesc)
      91                 :          17 :             Object.defineProperty(proto, underscoreName, propdesc);
      92         [ +  + ]:          24 :         if (!camelPropdesc)
      93                 :          21 :             Object.defineProperty(proto, camelName, propdesc);
      94                 :             :     }
      95                 :          12 : }
      96                 :             : 
      97                 :          81 : function _createClosure(builder, thisArg, handlerName, swapped, connectObject) {
      98         [ +  + ]:          81 :     connectObject ??= thisArg;
      99                 :             : 
     100         [ +  - ]:          81 :     if (swapped) {
     101                 :           0 :         throw new Error('Unsupported template signal flag "swapped"');
     102         [ +  - ]:          81 :     } else if (typeof thisArg[handlerName] === 'undefined') {
     103                 :           0 :         throw new Error(`A handler called ${handlerName} was not ` +
     104                 :           0 :             `defined on ${thisArg}`);
     105                 :             :     }
     106                 :             : 
     107                 :          81 :     return thisArg[handlerName].bind(connectObject);
     108                 :             : }
     109                 :             : 
     110                 :           8 : function _createBuilderConnectFunc(klass) {
     111                 :           8 :     const {GObject} = imports.gi;
     112                 :          46 :     return function (builder, obj, signalName, handlerName, connectObj, flags) {
     113                 :          38 :         const objects = builder.get_objects();
     114                 :         142 :         const thisObj = objects.find(o => o instanceof klass);
     115                 :          38 :         const swapped = flags & GObject.ConnectFlags.SWAPPED;
     116                 :          76 :         const closure = _createClosure(builder, thisObj, handlerName, swapped,
     117                 :          38 :             connectObj);
     118                 :             : 
     119         [ +  - ]:          38 :         if (flags & GObject.ConnectFlags.AFTER)
     120                 :           0 :             obj.connect_after(signalName, closure);
     121                 :             :         else
     122                 :          38 :             obj.connect(signalName, closure);
     123                 :             :     };
     124                 :           8 : }
        

Generated by: LCOV version 2.0-1