[gjs/wip/ptomato/develop: 1/4] coverage: Refactor bootstrap code to use ES6 classes



commit b302fac413a0714ba8567cfe7289d8b3e093478e
Author: Philip Chimento <philip chimento gmail com>
Date:   Sat Sep 23 13:08:45 2017 -0700

    coverage: Refactor bootstrap code to use ES6 classes
    
    This makes the code clearer because it's less dependent on variables
    being captured in closures. (Although there are still a few places where
    that is necessary in the debugger event handlers.)

 modules/_bootstrap/coverage.js |  269 +++++++++++++++++++++-------------------
 1 files changed, 139 insertions(+), 130 deletions(-)
---
diff --git a/modules/_bootstrap/coverage.js b/modules/_bootstrap/coverage.js
index 4365899..bd17783 100644
--- a/modules/_bootstrap/coverage.js
+++ b/modules/_bootstrap/coverage.js
@@ -1,3 +1,4 @@
+/* exported CoverageStatistics */
 /*
  * Copyright (c) 2014 Endless Mobile, Inc.
  *
@@ -677,15 +678,16 @@ function _incrementExpressionCounters(expressionCounters,
     expressionCounters[offsetLine]++;
 }
 
-function _BranchTracker(branchCounters) {
-    this._branchCounters = branchCounters;
-    this._activeBranch = undefined;
+var _BranchTracker = class {
+    constructor(branchCounters) {
+        this._branchCounters = branchCounters;
+        this._activeBranch = undefined;
+    }
 
-    this.incrementBranchCounters = function(offsetLine) {
+    incrementBranchCounters(offsetLine) {
         /* Set branch exits or find a new active branch */
-        let activeBranch = this._activeBranch;
-        if (activeBranch !== undefined) {
-            activeBranch.exits.forEach(function(exit) {
+        if (this._activeBranch) {
+            this._activeBranch.exits.forEach(function(exit) {
                 if (exit.line === offsetLine) {
                     exit.hitCount++;
                 }
@@ -695,17 +697,17 @@ function _BranchTracker(branchCounters) {
              * completely outside of it, since we might be in a case statement where
              * we need to check every possible option before jumping to an
              * exit */
-            if (offsetLine >= activeBranch.lastExit)
+            if (offsetLine >= this._activeBranch.lastExit)
                 this._activeBranch = undefined;
         }
 
-        let nextActiveBranch = branchCounters[offsetLine];
+        let nextActiveBranch = this._branchCounters[offsetLine];
         if (nextActiveBranch !== undefined) {
             this._activeBranch = nextActiveBranch;
             this._activeBranch.hit = true;
         }
-    };
-}
+    }
+};
 
 function _convertFunctionCountersToArray(functionCounters) {
     let arrayReturn = [];
@@ -790,19 +792,22 @@ function _fetchCountersFromReflection(filename, contents, nLines) {
     };
 }
 
-function CoverageStatisticsContainer(prefixes, cache) {
-    /* Copy the files array, so that it can be re-used in the tests */
-    let cachedASTs = cache ? JSON.parse(cache) : null;
-    let coveredFiles = {};
-    let cacheMisses = 0;
+var CoverageStatisticsContainer = class {
+    constructor(prefixes, cache) {
+        /* Copy the files array, so that it can be re-used in the tests */
+        this._cachedASTs = cache ? JSON.parse(cache) : null;
+        this._coveredFiles = {};
+        this._cacheMisses = 0;
+    }
 
-    function createStatisticsFor(filename) {
+    _createStatisticsFor(filename) {
         let contents = getFileContents(filename);
         let nLines = _getNumberOfLinesForScript(contents);
 
-        let counters = _fetchCountersFromCache(filename, cachedASTs, nLines);
+        let counters = _fetchCountersFromCache(filename, this._cachedASTs,
+            nLines);
         if (counters === null) {
-            cacheMisses++;
+            this._cacheMisses++;
             counters = _fetchCountersFromReflection(filename, contents, nLines);
         }
 
@@ -815,19 +820,19 @@ function CoverageStatisticsContainer(prefixes, cache) {
         return counters;
     }
 
-    function ensureStatisticsFor(filename) {
+    _ensureStatisticsFor(filename) {
         // Skip scripts fed to JS engine programmatically.
         if (filename.startsWith('<') && filename.endsWith('>'))
             return undefined;
-        if (!coveredFiles[filename])
-            coveredFiles[filename] = createStatisticsFor(filename);
-        return coveredFiles[filename];
+        if (!this._coveredFiles[filename])
+            this._coveredFiles[filename] = this._createStatisticsFor(filename);
+        return this._coveredFiles[filename];
     }
 
-    this.stringify = function() {
+    stringify() {
         let cache_data = {};
-        Object.keys(coveredFiles).forEach(function(filename) {
-            let statisticsForFilename = coveredFiles[filename];
+        Object.keys(this._coveredFiles).forEach(filename => {
+            let statisticsForFilename = this._coveredFiles[filename];
             let mtime = getFileModificationTime(filename);
             let cacheDataForFilename = {
                 mtime: mtime,
@@ -864,133 +869,137 @@ function CoverageStatisticsContainer(prefixes, cache) {
             cache_data[filename] = cacheDataForFilename;
         });
         return JSON.stringify(cache_data);
-    };
+    }
 
-    this.getCoveredFiles = function() {
-        return Object.keys(coveredFiles);
-    };
+    getCoveredFiles() {
+        return Object.keys(this._coveredFiles);
+    }
 
-    this.fetchStatistics = function(filename) {
-        return ensureStatisticsFor(filename);
-    };
+    fetchStatistics(filename) {
+        return this._ensureStatisticsFor(filename);
+    }
 
-    this.staleCache = function() {
-        return cacheMisses > 0;
-    };
+    staleCache() {
+        return this._cacheMisses > 0;
+    }
 
-    this.deleteStatistics = function(filename) {
-        coveredFiles[filename] = undefined;
-    };
-}
+    deleteStatistics(filename) {
+        this._coveredFiles[filename] = undefined;
+    }
+};
 
 /**
  * Main class tying together the Debugger object and CoverageStatisticsContainer.
  *
- * It isn't poissible to unit test this class because it depends on running
+ * It isn't possible to unit test this class because it depends on running
  * Debugger which in turn depends on objects injected in from another compartment */
-function CoverageStatistics(prefixes, cache, shouldWarn) {
-    this.container = new CoverageStatisticsContainer(prefixes, cache);
-    let fetchStatistics = this.container.fetchStatistics.bind(this.container);
-    let deleteStatistics = this.container.deleteStatistics.bind(this.container);
-
-    /* 'debuggee' comes from the invocation from
-     * a separate compartment inside of coverage.cpp */
-    this.dbg = new Debugger(debuggee);
+var CoverageStatistics = class {
+    constructor(prefixes, cache, shouldWarn) {
+        let _shouldWarn = shouldWarn;  // capture in closure
+        let container = new CoverageStatisticsContainer(prefixes, cache);
+        this.container = container;
+
+        /* 'debuggee' comes from the invocation from
+         * a separate compartment inside of coverage.cpp */
+        this.dbg = new Debugger(debuggee);
+        this.dbg.onEnterFrame = function (frame) {
+            let statistics;
 
-    this.getCoveredFiles = function() {
-        return this.container.getCoveredFiles();
-    };
-
-    this.getNumberOfLinesFor = function(filename) {
-        return fetchStatistics(filename).nLines;
-    };
-
-    this.getExecutedLinesFor = function(filename) {
-        return fetchStatistics(filename).expressionCounters;
-    };
+            try {
+                statistics = container.fetchStatistics(frame.script.url);
+                if (!statistics) {
+                    return undefined;
+                }
+            } catch (e) {
+                /* We don't care about this frame, return */
+                log(`${e.message} ${e.stack}`);
+                return undefined;
+            }
 
-    this.getBranchesFor = function(filename) {
-        return fetchStatistics(filename).branchCounters;
-    };
+            function _logExceptionAndReset(exception, callee, line) {
+                log(`${exception.fileName}:${exception.lineNumber} (processing ` +
+                    `${frame.script.url}:${callee}:${line}) - ${exception.message}`);
+                log('Will not log statistics for this file');
+                frame.onStep = undefined;
+                frame._branchTracker = undefined;
+                container.deleteStatistics(frame.script.url);
+            }
 
-    this.getFunctionsFor = function(filename) {
-        let functionCounters = fetchStatistics(filename).functionCounters;
-        return _convertFunctionCountersToArray(functionCounters);
-    };
+            /* Log function calls */
+            if (frame.callee !== null && frame.callee.callable) {
+                let name = frame.callee.name || '(anonymous)';
+                let {lineNumber} = frame.script.getOffsetLocation(frame.offset);
+                let nArgs = frame.callee.parameterNames.length;
+
+                try {
+                    _incrementFunctionCounters(statistics.functionCounters,
+                        statistics.linesWithKnownFunctions, name, lineNumber,
+                        nArgs);
+                } catch (e) {
+                    /* Something bad happened. Log the exception and delete
+                     * statistics for this file */
+                    _logExceptionAndReset(e, name, lineNumber);
+                    return undefined;
+                }
+            }
 
-    this.dbg.onEnterFrame = function(frame) {
-        let statistics;
+            /* Upon entering the frame, the active branch is always inactive */
+            frame._branchTracker = new _BranchTracker(statistics.branchCounters);
+
+            /* Set single-step hook */
+            frame.onStep = function() {
+                /* Line counts */
+                let {offset} = this;
+                let {lineNumber} = this.script.getOffsetLocation(offset);
+
+                try {
+                    _incrementExpressionCounters(statistics.expressionCounters,
+                        frame.script.url, lineNumber, _shouldWarn);
+                    this._branchTracker.incrementBranchCounters(lineNumber);
+                } catch (e) {
+                    /* Something bad happened. Log the exception and delete
+                     * statistics for this file */
+                    _logExceptionAndReset(e, frame.callee, lineNumber);
+                }
+            };
 
-        try {
-            statistics = fetchStatistics(frame.script.url);
-            if (!statistics) {
-                return undefined;
-            }
-        } catch (e) {
-            /* We don't care about this frame, return */
-            log(e.message + " " + e.stack);
             return undefined;
-        }
+        };
+    }
 
-        function _logExceptionAndReset(exception, callee, line) {
-            log(exception.fileName + ":" + exception.lineNumber +
-                " (processing " + frame.script.url + ":" + callee + ":" +
-                line + ") - " + exception.message);
-            log("Will not log statistics for this file");
-            frame.onStep = undefined;
-            frame._branchTracker = undefined;
-            deleteStatistics(frame.script.url);
-        }
+    getCoveredFiles() {
+        return this.container.getCoveredFiles();
+    }
 
-        /* Log function calls */
-        if (frame.callee !== null && frame.callee.callable) {
-            let name = frame.callee.name ? frame.callee.name : "(anonymous)";
-            let {lineNumber} = frame.script.getOffsetLocation(frame.offset);
-            let nArgs = frame.callee.parameterNames.length;
+    staleCache() {
+        return this.container.staleCache();
+    }
 
-            try {
-                _incrementFunctionCounters(statistics.functionCounters,
-                                           statistics.linesWithKnownFunctions,
-                                           name, lineNumber, nArgs);
-            } catch (e) {
-                /* Something bad happened. Log the exception and delete
-                 * statistics for this file */
-                _logExceptionAndReset(e, name, lineNumber);
-                return undefined;
-            }
-        }
+    stringify() {
+        return this.container.stringify();
+    }
 
-        /* Upon entering the frame, the active branch is always inactive */
-        frame._branchTracker = new _BranchTracker(statistics.branchCounters);
+    getNumberOfLinesFor(filename) {
+        return this.container.fetchStatistics(filename).nLines;
+    }
 
-        /* Set single-step hook */
-        frame.onStep = function() {
-            /* Line counts */
-            let offset = this.offset;
-            let {lineNumber} = this.script.getOffsetLocation(offset);
+    getExecutedLinesFor(filename) {
+        return this.container.fetchStatistics(filename).expressionCounters;
+    }
 
-            try {
-                _incrementExpressionCounters(statistics.expressionCounters,
-                                             frame.script.url,
-                                             lineNumber, shouldWarn);
-                this._branchTracker.incrementBranchCounters(lineNumber);
-            } catch (e) {
-                /* Something bad happened. Log the exception and delete
-                 * statistics for this file */
-                _logExceptionAndReset(e, frame.callee, lineNumber);
-            }
-        };
+    getBranchesFor(filename) {
+        return this.container.fetchStatistics(filename).branchCounters;
+    }
 
-        return undefined;
-    };
+    getFunctionsFor(filename) {
+        let {functionCounters} = this.container.fetchStatistics(filename);
+        return _convertFunctionCountersToArray(functionCounters);
+    }
 
-    this.deactivate = function() {
+    deactivate() {
         /* This property is designed to be a one-stop-shop to
-         * disable the debugger for this debugee, without having
+         * disable the debugger for this debuggee, without having
          * to traverse all its scripts or frames */
         this.dbg.enabled = false;
-    };
-
-    this.staleCache = this.container.staleCache.bind(this.container);
-    this.stringify = this.container.stringify.bind(this.container);
-}
+    }
+};


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]