# Global Metrics

path: .metrics.cognitive.sum
old: 0.0
new: 1.0
path: .metrics.cognitive.average
old: 0.0
new: 0.058823529411764705
path: .metrics.nexits.sum
old: 0.0
new: 6.0
path: .metrics.nexits.average
old: 0.0
new: 0.35294117647058826
path: .metrics.nargs.average
old: 0.0
new: 0.4117647058823529
path: .metrics.nargs.sum
old: 0.0
new: 7.0
path: .metrics.nom.total
old: 1.0
new: 17.0
path: .metrics.nom.functions
old: 1.0
new: 17.0
path: .metrics.cyclomatic.average
old: 1.0
new: 1.318181818181818
path: .metrics.cyclomatic.sum
old: 5.0
new: 29.0
path: .metrics.mi.mi_visual_studio
old: 38.368347146440925
new: 27.796422685956298
path: .metrics.mi.mi_original
old: 65.60987362041398
new: 47.53188279298526
path: .metrics.mi.mi_sei
old: 58.03765837266502
new: 33.15313015509651
path: .metrics.loc.blank
old: 8.0
new: 21.0
path: .metrics.loc.ploc
old: 38.0
new: 67.0
path: .metrics.loc.sloc
old: 68.0
new: 125.0
path: .metrics.loc.cloc
old: 22.0
new: 37.0
path: .metrics.loc.lloc
old: 7.0
new: 13.0
path: .metrics.halstead.volume
old: 993.0576916718502
new: 1667.5688237022168
path: .metrics.halstead.N2
old: 81.0
new: 108.0
path: .metrics.halstead.effort
old: 9831.271147551315
new: 62102.5630895998
path: .metrics.halstead.n2
old: 45.0
new: 29.0
path: .metrics.halstead.estimated_program_length
old: 285.1871371398456
new: 227.32001075644683
path: .metrics.halstead.n1
old: 11.0
new: 20.0
path: .metrics.halstead.N1
old: 90.0
new: 189.0
path: .metrics.halstead.length
old: 171.0
new: 297.0
path: .metrics.halstead.purity_ratio
old: 1.66776103590553
new: 0.7653872416041981
path: .metrics.halstead.difficulty
old: 9.9
new: 37.241379310344826
path: .metrics.halstead.level
old: 0.101010101010101
new: 0.026851851851851852
path: .metrics.halstead.vocabulary
old: 56.0
new: 49.0
path: .metrics.halstead.bugs
old: 0.1529743188378401
new: 0.5227392315268155
path: .metrics.halstead.time
old: 546.1817304195176
new: 3450.1423938666553

# Spaces Data

## Minimal test - lines (43, 43)

path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.level
old: null
new: 0.3333333333333333
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.vocabulary
old: 1.0
new: 8.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.length
old: 1.0
new: 10.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.volume
old: 0.0
new: 30.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.purity_ratio
old: null
new: 1.7509775004326935
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.N1
old: 0.0
new: 8.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.effort
old: 0.0
new: 90.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.n1
old: 0.0
new: 6.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.n2
old: 1.0
new: 2.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.bugs
old: 0.0
new: 0.006694329500821694
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.N2
old: 1.0
new: 2.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.difficulty
old: 0.0
new: 3.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: null
new: 17.509775004326936
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.halstead.time
old: 0.0
new: 5.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.nexits.sum
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.nexits.average
old: null
new: 1.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: null
new: 89.52267462886361
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.mi.mi_original
old: null
new: 153.0837736153568
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.mi.mi_sei
old: null
new: 145.25416890283572
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.cognitive.average
old: null
new: 0.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.nom.functions
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.nom.total
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.nargs.average
old: null
new: 0.0
path: .spaces[0].spaces[0].spaces[0].spaces[0].metrics.loc.lloc
old: 0.0
new: 1.0

### Code

        T* operator->() const& { return &ref(); }

## Minimal test - lines (14, 123)

path: .spaces[0].metrics.cyclomatic.sum
old: 4.0
new: 28.0
path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 1.3333333333333333
path: .spaces[0].metrics.nexits.average
old: 0.0
new: 0.35294117647058826
path: .spaces[0].metrics.nexits.sum
old: 0.0
new: 6.0
path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 1.0
path: .spaces[0].metrics.cognitive.average
old: 0.0
new: 0.058823529411764705
path: .spaces[0].metrics.nom.functions
old: 1.0
new: 17.0
path: .spaces[0].metrics.nom.total
old: 1.0
new: 17.0
path: .spaces[0].metrics.mi.mi_visual_studio
old: 40.594346395795455
new: 29.2329831871729
path: .spaces[0].metrics.mi.mi_original
old: 69.41633233681023
new: 49.98840125006565
path: .spaces[0].metrics.mi.mi_sei
old: 61.93706617403583
new: 35.449363072364825
path: .spaces[0].metrics.nargs.average
old: 0.0
new: 0.4117647058823529
path: .spaces[0].metrics.nargs.sum
old: 0.0
new: 7.0
path: .spaces[0].metrics.loc.cloc
old: 16.0
new: 30.0
path: .spaces[0].metrics.loc.lloc
old: 7.0
new: 13.0
path: .spaces[0].metrics.loc.sloc
old: 55.0
new: 110.0
path: .spaces[0].metrics.loc.ploc
old: 34.0
new: 61.0
path: .spaces[0].metrics.loc.blank
old: 5.0
new: 19.0
path: .spaces[0].metrics.halstead.volume
old: 966.8211003634626
new: 1618.4036531247048
path: .spaces[0].metrics.halstead.N2
old: 78.0
new: 104.0
path: .spaces[0].metrics.halstead.bugs
old: 0.15104350317976994
new: 0.5374152336913978
path: .spaces[0].metrics.halstead.estimated_program_length
old: 271.3831322572005
new: 208.64999456941564
path: .spaces[0].metrics.halstead.level
old: 0.10023310023310024
new: 0.025
path: .spaces[0].metrics.halstead.n2
old: 43.0
new: 26.0
path: .spaces[0].metrics.halstead.length
old: 168.0
new: 293.0
path: .spaces[0].metrics.halstead.purity_ratio
old: 1.615375787245241
new: 0.7121160224212137
path: .spaces[0].metrics.halstead.N1
old: 90.0
new: 189.0
path: .spaces[0].metrics.halstead.vocabulary
old: 54.0
new: 46.0
path: .spaces[0].metrics.halstead.difficulty
old: 9.976744186046512
new: 40.0
path: .spaces[0].metrics.halstead.effort
old: 9645.726791998266
new: 64736.14612498819
path: .spaces[0].metrics.halstead.time
old: 535.8737106665703
new: 3596.452562499344
path: .spaces[0].metrics.halstead.n1
old: 11.0
new: 20.0

### Code

    namespace mozilla {

    // A template to wrap a type with a mutex so that accesses to the type's
    // data are required to take the lock before accessing it. This ensures
    // that a mutex is explicitly associated with the data that it protects,
    // and makes it impossible to access the data without first taking the
    // associated mutex.
    //
    // This is based on Rust's std::sync::Mutex, which operates under the
    // strategy of locking data, rather than code.
    //
    // Examples:
    //
    //    DataMutex u32DataMutex(1, "u32DataMutex");
    //    auto x = u32DataMutex.Lock();
    //    *x = 4;
    //    assert(*x, 4u);
    //
    //    DataMutex> arrayDataMutex("arrayDataMutex");
    //    auto a = arrayDataMutex.Lock();
    //    auto& x = a.ref();
    //    x.AppendElement(1u);
    //    assert(x[0], 1u);
    //
    template
    class DataMutexBase {
     public:
      class MOZ_STACK_CLASS AutoLock {
       public:
        T* operator->() const& { return &ref(); }
        T* operator->() const&& = delete;

        T& operator*() const& { return ref(); }
        T& operator*() const&& = delete;

        // Like RefPtr, make this act like its underlying raw pointer type
        // whenever it is used in a context where a raw pointer is expected.
        operator T*() const& { return &ref(); }

        // Like RefPtr, don't allow implicit conversion of temporary to raw pointer.
        operator T*() const&& = delete;

        T& ref() const& {
          MOZ_ASSERT(mOwner);
          return mOwner->mValue;
        }
        T& ref() const&& = delete;

        AutoLock(AutoLock&& aOther) : mOwner(aOther.mOwner) {
          aOther.mOwner = nullptr;
        }

        ~AutoLock() {
          if (mOwner) {
            mOwner->mMutex.Unlock();
            mOwner = nullptr;
          }
        }

       private:
        friend class DataMutexBase;

        AutoLock(const AutoLock& aOther) = delete;

        explicit AutoLock(DataMutexBase* aDataMutex)
            : mOwner(aDataMutex) {
          MOZ_ASSERT(!!mOwner);
          mOwner->mMutex.Lock();
        }

        DataMutexBase* mOwner;
      };

      explicit DataMutexBase(const char* aName) : mMutex(aName) {}

      DataMutexBase(T&& aValue, const char* aName)
          : mMutex(aName), mValue(std::move(aValue)) {}

      AutoLock Lock() { return AutoLock(this); }

      const MutexType& Mutex() const { return mMutex; }

     private:
      MutexType mMutex;
      T mValue;
    };

    // Craft a version of StaticMutex that takes a const char* in its ctor.
    // We need this so it works interchangeably with Mutex which requires a const
    // char* aName in its ctor.
    class StaticMutexNameless : public StaticMutex {
     public:
      explicit StaticMutexNameless(const char* aName) : StaticMutex() {}

     private:
      // Disallow copy construction, `=`, `new`, and `delete` like BaseStaticMutex.
    #ifdef DEBUG
      StaticMutexNameless(StaticMutexNameless& aOther);
    #endif  // DEBUG
      StaticMutexNameless& operator=(StaticMutexNameless* aRhs);
      static void* operator new(size_t) noexcept(true);
      static void operator delete(void*);
    };

    template
    using DataMutex = DataMutexBase;
    template
    using StaticDataMutex = DataMutexBase;

    }  // namespace mozilla

## Minimal test - lines (41, 85)

path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_original
old: 71.95418488633987
new: 70.16968782314429
path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_sei
old: 66.10950169086291
new: 46.938103095281505
path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 42.07847069376601
new: 41.0349051597335
path: .spaces[0].spaces[0].spaces[0].metrics.cyclomatic.sum
old: 2.0
new: 19.0
path: .spaces[0].spaces[0].spaces[0].metrics.cyclomatic.average
old: 1.0
new: 1.4615384615384617
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.bugs
old: 0.14923510764419115
new: 0.30695978917863226
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 257.7133799943517
new: 128.36161893476807
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.level
old: 0.09808612440191387
new: 0.02880658436213992
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.n2
old: 41.0
new: 14.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.length
old: 163.0
new: 161.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.effort
old: 9473.018530629884
new: 27945.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.time
old: 526.2788072572157
new: 1552.5
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.n1
old: 11.0
new: 18.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.volume
old: 929.171674056998
new: 805.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.vocabulary
old: 52.0
new: 32.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 1.5810636809469432
new: 0.7972771362407955
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.N2
old: 76.0
new: 54.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.difficulty
old: 10.195121951219512
new: 34.714285714285715
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.N1
old: 87.0
new: 107.0
path: .spaces[0].spaces[0].spaces[0].metrics.nexits.sum
old: 0.0
new: 4.0
path: .spaces[0].spaces[0].spaces[0].metrics.nexits.average
old: 0.0
new: 0.3333333333333333
path: .spaces[0].spaces[0].spaces[0].metrics.nargs.sum
old: 0.0
new: 3.0
path: .spaces[0].spaces[0].spaces[0].metrics.nargs.average
old: 0.0
new: 0.25
path: .spaces[0].spaces[0].spaces[0].metrics.nom.functions
old: 1.0
new: 12.0
path: .spaces[0].spaces[0].spaces[0].metrics.nom.total
old: 1.0
new: 12.0
path: .spaces[0].spaces[0].spaces[0].metrics.loc.cloc
old: 15.0
new: 3.0
path: .spaces[0].spaces[0].spaces[0].metrics.loc.lloc
old: 6.0
new: 11.0
path: .spaces[0].spaces[0].spaces[0].metrics.loc.blank
old: 4.0
new: 10.0
path: .spaces[0].spaces[0].spaces[0].metrics.loc.ploc
old: 30.0
new: 32.0
path: .spaces[0].spaces[0].spaces[0].metrics.loc.sloc
old: 49.0
new: 45.0
path: .spaces[0].spaces[0].spaces[0].metrics.cognitive.sum
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].metrics.cognitive.average
old: 0.0
new: 0.08333333333333333

### Code

      class MOZ_STACK_CLASS AutoLock {
       public:
        T* operator->() const& { return &ref(); }
        T* operator->() const&& = delete;

        T& operator*() const& { return ref(); }
        T& operator*() const&& = delete;

        // Like RefPtr, make this act like its underlying raw pointer type
        // whenever it is used in a context where a raw pointer is expected.
        operator T*() const& { return &ref(); }

        // Like RefPtr, don't allow implicit conversion of temporary to raw pointer.
        operator T*() const&& = delete;

        T& ref() const& {
          MOZ_ASSERT(mOwner);
          return mOwner->mValue;
        }
        T& ref() const&& = delete;

        AutoLock(AutoLock&& aOther) : mOwner(aOther.mOwner) {
          aOther.mOwner = nullptr;
        }

        ~AutoLock() {
          if (mOwner) {
            mOwner->mMutex.Unlock();
            mOwner = nullptr;
          }
        }

       private:
        friend class DataMutexBase;

        AutoLock(const AutoLock& aOther) = delete;

        explicit AutoLock(DataMutexBase* aDataMutex)
            : mOwner(aDataMutex) {
          MOZ_ASSERT(!!mOwner);
          mOwner->mMutex.Lock();
        }

        DataMutexBase* mOwner;
      };

## Minimal test - lines (39, 99)

path: .spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 1.593560720251315
new: 0.7374301914324605
path: .spaces[0].spaces[0].metrics.halstead.length
old: 166.0
new: 219.0
path: .spaces[0].spaces[0].metrics.halstead.volume
old: 950.8347954574908
new: 1149.2961254441452
path: .spaces[0].spaces[0].metrics.halstead.vocabulary
old: 53.0
new: 38.0
path: .spaces[0].spaces[0].metrics.halstead.N2
old: 77.0
new: 78.0
path: .spaces[0].spaces[0].metrics.halstead.time
old: 532.6435659738722
new: 2766.8240056988684
path: .spaces[0].spaces[0].metrics.halstead.n1
old: 11.0
new: 20.0
path: .spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 264.53107956171823
new: 161.49721192370885
path: .spaces[0].spaces[0].metrics.halstead.n2
old: 42.0
new: 18.0
path: .spaces[0].spaces[0].metrics.halstead.bugs
old: 0.15043591743468346
new: 0.45121282859473894
path: .spaces[0].spaces[0].metrics.halstead.difficulty
old: 10.083333333333334
new: 43.333333333333336
path: .spaces[0].spaces[0].metrics.halstead.level
old: 0.09917355371900824
new: 0.023076923076923075
path: .spaces[0].spaces[0].metrics.halstead.effort
old: 9587.5841875297
new: 49802.83210257963
path: .spaces[0].spaces[0].metrics.halstead.N1
old: 89.0
new: 141.0
path: .spaces[0].spaces[0].metrics.loc.cloc
old: 15.0
new: 3.0
path: .spaces[0].spaces[0].metrics.loc.ploc
old: 32.0
new: 43.0
path: .spaces[0].spaces[0].metrics.loc.sloc
old: 53.0
new: 61.0
path: .spaces[0].spaces[0].metrics.loc.lloc
old: 7.0
new: 13.0
path: .spaces[0].spaces[0].metrics.loc.blank
old: 6.0
new: 15.0
path: .spaces[0].spaces[0].metrics.nargs.sum
old: 0.0
new: 6.0
path: .spaces[0].spaces[0].metrics.nargs.average
old: 0.0
new: 0.375
path: .spaces[0].spaces[0].metrics.mi.mi_sei
old: 62.77281568488872
new: 33.14808576872802
path: .spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 41.130468584980015
new: 36.2631213806286
path: .spaces[0].spaces[0].metrics.mi.mi_original
old: 70.33310128031583
new: 62.0099375608749
path: .spaces[0].spaces[0].metrics.cyclomatic.sum
old: 3.0
new: 25.0
path: .spaces[0].spaces[0].metrics.cyclomatic.average
old: 1.0
new: 1.3888888888888888
path: .spaces[0].spaces[0].metrics.nexits.sum
old: 0.0
new: 6.0
path: .spaces[0].spaces[0].metrics.nexits.average
old: 0.0
new: 0.375
path: .spaces[0].spaces[0].metrics.cognitive.average
old: 0.0
new: 0.0625
path: .spaces[0].spaces[0].metrics.cognitive.sum
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].metrics.nom.total
old: 1.0
new: 16.0
path: .spaces[0].spaces[0].metrics.nom.functions
old: 1.0
new: 16.0

### Code

    class DataMutexBase {
     public:
      class MOZ_STACK_CLASS AutoLock {
       public:
        T* operator->() const& { return &ref(); }
        T* operator->() const&& = delete;

        T& operator*() const& { return ref(); }
        T& operator*() const&& = delete;

        // Like RefPtr, make this act like its underlying raw pointer type
        // whenever it is used in a context where a raw pointer is expected.
        operator T*() const& { return &ref(); }

        // Like RefPtr, don't allow implicit conversion of temporary to raw pointer.
        operator T*() const&& = delete;

        T& ref() const& {
          MOZ_ASSERT(mOwner);
          return mOwner->mValue;
        }
        T& ref() const&& = delete;

        AutoLock(AutoLock&& aOther) : mOwner(aOther.mOwner) {
          aOther.mOwner = nullptr;
        }

        ~AutoLock() {
          if (mOwner) {
            mOwner->mMutex.Unlock();
            mOwner = nullptr;
          }
        }

       private:
        friend class DataMutexBase;

        AutoLock(const AutoLock& aOther) = delete;

        explicit AutoLock(DataMutexBase* aDataMutex)
            : mOwner(aDataMutex) {
          MOZ_ASSERT(!!mOwner);
          mOwner->mMutex.Lock();
        }

        DataMutexBase* mOwner;
      };

      explicit DataMutexBase(const char* aName) : mMutex(aName) {}

      DataMutexBase(T&& aValue, const char* aName)
          : mMutex(aName), mValue(std::move(aValue)) {}

      AutoLock Lock() { return AutoLock(this); }

      const MutexType& Mutex() const { return mMutex; }

     private:
      MutexType mMutex;
      T mValue;
    };