emacs-elpa-diffs
[Top][All Lists]
Advanced

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

[elpa] master 2cdd91e 043/271: Write new scopifier with comment detectio


From: Jackson Ray Hamilton
Subject: [elpa] master 2cdd91e 043/271: Write new scopifier with comment detection.
Date: Thu, 05 Feb 2015 18:29:38 +0000

branch: master
commit 2cdd91ef433aff628d63bb6f7f7e280fea78616a
Author: Jackson Ray Hamilton <address@hidden>
Commit: Jackson Ray Hamilton <address@hidden>

    Write new scopifier with comment detection.
---
 context-coloring.el    |   12 ++++-
 package.json           |    2 +
 scopifier-esprima.js   |  123 ++++++++++++++++++++++++++++++++++++++++++++++++
 test/fixtures/monad.js |    2 +
 4 files changed, 136 insertions(+), 3 deletions(-)

diff --git a/context-coloring.el b/context-coloring.el
index d98eb9b..98edb8b 100644
--- a/context-coloring.el
+++ b/context-coloring.el
@@ -41,6 +41,12 @@
 
 ;;; Faces
 
+(defface context-coloring-depth--1-face
+  '((((background light)) (:foreground "#999999"))
+    (((background dark)) (:foreground "#999999")))
+  "Nested blocks face, depth -1; comments."
+  :group 'context-coloring-faces)
+
 (defface context-coloring-depth-0-face
   '((((background light)) (:foreground "#ffffff"))
     (((background dark)) (:foreground "#ffffff")))
@@ -121,7 +127,7 @@ For example: \"context-coloring-depth-1-face\"."
   "This file's directory.")
 
 (defconst context-coloring-scopifier-path
-  (expand-file-name "./scopifier.js" context-coloring-path)
+  (expand-file-name "./scopifier-esprima.js" context-coloring-path)
   "Path to the external scopifier executable.")
 
 (defconst context-coloring-delay 0.25
@@ -187,7 +193,7 @@ calling FUNCTION with the parsed list of tokens."
                                 (with-current-buffer buffer
                                   (context-coloring-apply-tokens tokens))
                                 (setq context-coloring-scopifier-process nil)
-                                ;; (message "Colorized (after %f seconds)." (- 
(float-time) start-time))
+                                (message "Colorized (after %f seconds)." (- 
(float-time) start-time))
                                 )))))
 
   ;; Give the process its input.
@@ -200,7 +206,7 @@ calling FUNCTION with the parsed list of tokens."
 (defun context-coloring-colorize ()
   (interactive)
   (setq context-coloring-colorize-start-time (float-time))
-  ;; (message "%s" "Colorizing.")
+  (message "%s" "Colorizing.")
   (context-coloring-scopify))
 
 (defun context-coloring-change-function (start end length)
diff --git a/package.json b/package.json
index c5cd241..09d3be2 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,8 @@
     "mocha": "^2.0.1"
   },
   "dependencies": {
+    "escope": "^1.0.1",
+    "esprima": "^1.2.2",
     "uglify-js": "^2.4.15"
   }
 }
diff --git a/scopifier-esprima.js b/scopifier-esprima.js
new file mode 100644
index 0000000..29bdc85
--- /dev/null
+++ b/scopifier-esprima.js
@@ -0,0 +1,123 @@
+/*jslint node: true */
+
+'use strict';
+
+var escope = require('escope'),
+    esprima = require('esprima'),
+    whole = '';
+
+process.stdin.setEncoding('utf8');
+
+process.stdin.on('readable', function () {
+    var chunk = process.stdin.read();
+    if (chunk !== null) {
+        whole += chunk;
+    }
+});
+
+process.stdin.on('end', function () {
+    var ast,
+        analyzedScopes,
+        scopes = [],
+        symbols = [],
+        comments = [],
+        emacsified;
+
+    // Gracefully handle parse errors by doing nothing.
+    try {
+        ast = esprima.parse(whole, {
+            comment: true,
+            range: true
+        });
+        analyzedScopes = escope.analyze(ast).scopes;
+    } catch (error) {
+        process.exit(1);
+    }
+
+    analyzedScopes.forEach(function (scope) {
+        if (scope.level === undefined) {
+            if (scope.upper) {
+                if (scope.upper.functionExpressionScope) {
+                    // Pretend function expression scope doesn't exist.
+                    scope.level = scope.upper.level;
+                    scope.variables = 
scope.upper.variables.concat(scope.variables);
+                } else {
+                    scope.level = scope.upper.level + 1;
+                }
+            } else {
+                scope.level = 0;
+            }
+            if (scope.functionExpressionScope) {
+                // We've only given the scope a level for posterity's sake.
+                return;
+            }
+            scopes.push([
+                scope.level,
+                scope.block.range[0],
+                scope.block.range[1]
+            ]);
+            scope.variables.forEach(function (variable) {
+                var definitions = [],
+                    references = [];
+                variable.defs.forEach(function (definition) {
+                    var range = definition.name.range;
+                    definitions.push([
+                        scope.level,
+                        range[0],
+                        range[1]
+                    ]);
+                });
+                variable.references.forEach(function (reference) {
+                    var range = reference.identifier.range,
+                        isDefined = definitions.some(function (definition) {
+                            // Check for identical definitions.
+                            return definition[1] === range[0] &&
+                                definition[2] === range[1];
+                        });
+                    if (isDefined) {
+                        return;
+                    }
+                    references.push([
+                        scope.level,
+                        range[0],
+                        range[1]
+                    ]);
+                });
+                Array.prototype.push.apply(symbols, definitions);
+                Array.prototype.push.apply(symbols, references);
+            });
+            scope.references.forEach(function (reference) {
+                var range;
+                if (reference.resolved) {
+                    return;
+                }
+                // Handle global references.
+                range = reference.identifier.range;
+                symbols.push([
+                    0,
+                    range[0],
+                    range[1]
+                ]);
+            });
+        }
+    });
+
+    ast.comments.forEach(function (comment) {
+        var range = comment.range;
+        comments.push([
+            -1,
+            range[0],
+            range[1]
+        ]);
+    });
+
+    emacsified = scopes.concat(symbols.concat(comments));
+
+    emacsified.forEach(function (instruction) {
+        // Emacs starts counting from 1.
+        instruction[1] += 1;
+        instruction[2] += 1;
+    });
+
+    console.log(JSON.stringify(emacsified));
+});
diff --git a/test/fixtures/monad.js b/test/fixtures/monad.js
index 4a2e19c..7a90405 100644
--- a/test/fixtures/monad.js
+++ b/test/fixtures/monad.js
@@ -1,5 +1,7 @@
+/* A monad. */
 function MONAD() {
     return function unit(value) {
+        // Some details.
         var monad = Object.create(null);
         monad.bind = function (func) {
             return func(value);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]