Global Metrics

path: .metrics.halstead.purity_ratio
old: 1.3546953537145312
new: 0.9844312689138702

path: .metrics.halstead.effort
old: 130002.6132808472
new: 71073.91479577204

path: .metrics.halstead.n2
old: 153.0
new: 47.0

path: .metrics.halstead.volume
old: 6342.601987235211
new: 2141.3294842315936

path: .metrics.halstead.time
old: 7222.367404491511
new: 3948.550821987335

path: .metrics.halstead.difficulty
old: 20.49673202614379
new: 33.191489361702125

path: .metrics.halstead.N1
old: 411.0
new: 197.0

path: .metrics.halstead.estimated_program_length
old: 1163.6833088407825
new: 347.5042379265962

path: .metrics.halstead.vocabulary
old: 167.0
new: 67.0

path: .metrics.halstead.N2
old: 448.0
new: 156.0

path: .metrics.halstead.length
old: 859.0
new: 353.0

path: .metrics.halstead.bugs
old: 0.8554214449783866
new: 0.5719423254376421

path: .metrics.halstead.level
old: 0.04878826530612245
new: 0.030128205128205132

path: .metrics.halstead.n1
old: 14.0
new: 20.0

path: .metrics.cognitive.average
old: 0.0
new: 1.7142857142857142

path: .metrics.cognitive.sum
old: 0.0
new: 12.0

path: .metrics.mi.mi_original
old: 36.013667506833215
new: 47.52659684176558

path: .metrics.mi.mi_visual_studio
old: 21.06062427300188
new: 27.793331486412622

path: .metrics.mi.mi_sei
old: 1.4593975294348986
new: 26.934832078664627

path: .metrics.nom.functions
old: 1.0
new: 7.0

path: .metrics.nom.total
old: 1.0
new: 7.0

path: .metrics.loc.lloc
old: 2.0
new: 26.0

path: .metrics.loc.blank
old: 11.0
new: 20.0

path: .metrics.loc.ploc
old: 178.0
new: 86.0

path: .metrics.loc.cloc
old: 22.0
new: 27.0

path: .metrics.loc.sloc
old: 211.0
new: 133.0

path: .metrics.nexits.sum
old: 1.0
new: 7.0

path: .metrics.nargs.average
old: 0.0
new: 1.7142857142857142

path: .metrics.nargs.sum
old: 0.0
new: 12.0

path: .metrics.cyclomatic.sum
old: 12.0
new: 19.0

path: .metrics.cyclomatic.average
old: 1.0
new: 1.9

Spaces Data

Minimal test - lines (17, 131)

path: .spaces[0].metrics.nom.total
old: 0.0
new: 7.0

path: .spaces[0].metrics.nom.functions
old: 0.0
new: 7.0

path: .spaces[0].metrics.halstead.level
old: null
new: 0.028

path: .spaces[0].metrics.halstead.volume
old: 0.0
new: 2066.1061197042454

path: .spaces[0].metrics.halstead.purity_ratio
old: null
new: 0.901774909667018

path: .spaces[0].metrics.halstead.vocabulary
old: 1.0
new: 62.0

path: .spaces[0].metrics.halstead.length
old: 1.0
new: 347.0

path: .spaces[0].metrics.halstead.difficulty
old: 0.0
new: 35.714285714285715

path: .spaces[0].metrics.halstead.effort
old: 0.0
new: 73789.50427515163

path: .spaces[0].metrics.halstead.n1
old: 0.0
new: 20.0

path: .spaces[0].metrics.halstead.n2
old: 1.0
new: 42.0

path: .spaces[0].metrics.halstead.N2
old: 1.0
new: 150.0

path: .spaces[0].metrics.halstead.time
old: 0.0
new: 4099.41690417509

path: .spaces[0].metrics.halstead.N1
old: 0.0
new: 197.0

path: .spaces[0].metrics.halstead.bugs
old: 0.0
new: 0.5864195951257065

path: .spaces[0].metrics.halstead.estimated_program_length
old: null
new: 312.9158936544552

path: .spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 18.0

path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 2.0

path: .spaces[0].metrics.loc.sloc
old: 1.0
new: 115.0

path: .spaces[0].metrics.loc.lloc
old: 0.0
new: 26.0

path: .spaces[0].metrics.loc.blank
old: 0.0
new: 17.0

path: .spaces[0].metrics.loc.cloc
old: 0.0
new: 20.0

path: .spaces[0].metrics.loc.ploc
old: 1.0
new: 78.0

path: .spaces[0].metrics.nargs.average
old: null
new: 1.7142857142857142

path: .spaces[0].metrics.nargs.sum
old: 0.0
new: 12.0

path: .spaces[0].metrics.mi.mi_original
old: null
new: 50.2983102520119

path: .spaces[0].metrics.mi.mi_sei
old: null
new: 28.799216991517465

path: .spaces[0].metrics.mi.mi_visual_studio
old: null
new: 29.41421652164439

path: .spaces[0].metrics.nexits.sum
old: 0.0
new: 7.0

path: .spaces[0].metrics.nexits.average
old: null
new: 1.0

path: .spaces[0].metrics.cognitive.average
old: null
new: 1.7142857142857142

path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 12.0

Code

namespace mozilla {

/**
 * This class will wrap a nsIRunnable and dispatch it to the main thread
 * synchronously. This is different from nsIEventTarget.DISPATCH_SYNC:
 * this class does not spin the event loop waiting for the event to be
 * dispatched. This means that you don't risk reentrance from pending
 * messages, but you must be sure that the target thread does not ever block
 * on this thread, or else you will deadlock.
 *
 * Typical usage:
 * RefPtr sr = new SyncRunnable(new myrunnable...());
 * sr->DispatchToThread(t);
 *
 * We also provide a convenience wrapper:
 * SyncRunnable::DispatchToThread(new myrunnable...());
 *
 */
class SyncRunnable : public Runnable {
 public:
  explicit SyncRunnable(nsIRunnable* aRunnable)
      : Runnable("SyncRunnable"),
        mRunnable(aRunnable),
        mMonitor("SyncRunnable"),
        mDone(false) {}

  explicit SyncRunnable(already_AddRefed aRunnable)
      : Runnable("SyncRunnable"),
        mRunnable(std::move(aRunnable)),
        mMonitor("SyncRunnable"),
        mDone(false) {}

  nsresult DispatchToThread(nsIEventTarget* aThread,
                            bool aForceDispatch = false) {
    nsresult rv;
    bool on;

    if (!aForceDispatch) {
      rv = aThread->IsOnCurrentThread(&on);
      MOZ_ASSERT(NS_SUCCEEDED(rv));
      if (NS_SUCCEEDED(rv) && on) {
        mRunnable->Run();
        return NS_OK;
      }
    }

    rv = aThread->Dispatch(this, NS_DISPATCH_NORMAL);
    if (NS_SUCCEEDED(rv)) {
      mozilla::MonitorAutoLock lock(mMonitor);
      // This could be synchronously dispatching to a thread currently waiting
      // for JS execution clearance. Yield JS execution.
      dom::AutoYieldJSThreadExecution yield;

      while (!mDone) {
        lock.Wait();
      }
    }
    return rv;
  }

  nsresult DispatchToThread(AbstractThread* aThread,
                            bool aForceDispatch = false) {
    if (!aForceDispatch && aThread->IsCurrentThreadIn()) {
      mRunnable->Run();
      return NS_OK;
    }

    // Check we don't have tail dispatching here. Otherwise we will deadlock
    // ourself when spinning the loop below.
    MOZ_ASSERT(!aThread->RequiresTailDispatchFromCurrentThread());

    nsresult rv = aThread->Dispatch(RefPtr(this).forget());
    if (NS_SUCCEEDED(rv)) {
      mozilla::MonitorAutoLock lock(mMonitor);
      while (!mDone) {
        lock.Wait();
      }
    }
    return rv;
  }

  static nsresult DispatchToThread(nsIEventTarget* aThread,
                                   nsIRunnable* aRunnable,
                                   bool aForceDispatch = false) {
    RefPtr s(new SyncRunnable(aRunnable));
    return s->DispatchToThread(aThread, aForceDispatch);
  }

  static nsresult DispatchToThread(AbstractThread* aThread,
                                   nsIRunnable* aRunnable,
                                   bool aForceDispatch = false) {
    RefPtr s(new SyncRunnable(aRunnable));
    return s->DispatchToThread(aThread, aForceDispatch);
  }

 protected:
  NS_IMETHOD Run() override {
    mRunnable->Run();

    mozilla::MonitorAutoLock lock(mMonitor);
    MOZ_ASSERT(!mDone);

    mDone = true;
    mMonitor.Notify();

    return NS_OK;
  }

 private:
  nsCOMPtr mRunnable;
  mozilla::Monitor mMonitor;
  bool mDone;
};

}  // namespace mozilla