]>
code.delx.au - gnu-emacs-elpa/blob - scopifier.js
5 var escope
= require('escope'),
6 esprima
= require('esprima'),
8 // Given an array of definitions, determines if a definition already exists
9 // for a given range. (escope detects variables twice if they are declared
10 // and initialized simultaneously; this filters them.)
11 isDefined = function (definitions
, range
) {
12 return definitions
.some(function (definition
) {
13 // Check for identical definitions.
14 return definition
[1] === range
[0] &&
15 definition
[2] === range
[1];
19 // Given code, returns an array of `[level, start, end]' tokens for
21 module
.exports = function (code
) {
29 // Gracefully handle parse errors by doing nothing.
31 ast
= esprima
.parse(code
, {
35 analyzedScopes
= escope
.analyze(ast
).scopes
;
40 analyzedScopes
.forEach(function (scope
) {
42 if (scope
.level
!== undefined) {
46 if (scope
.upper
.functionExpressionScope
) {
47 // Pretend function expression scope doesn't exist.
48 scope
.level
= scope
.upper
.level
;
49 scope
.variables
= scope
.upper
.variables
.concat(scope
.variables
);
51 scope
.level
= scope
.upper
.level
+ 1;
56 if (scope
.functionExpressionScope
) {
57 // We've only given the scope a level for posterity's sake.
65 scopeDefinitions
= [];
66 scope
.variables
.forEach(function (variable
) {
69 variable
.defs
.forEach(function (definition
) {
70 var range
= definition
.name
.range
;
77 variable
.references
.forEach(function (reference
) {
78 var range
= reference
.identifier
.range
;
79 if (isDefined(definitions
, range
)) {
88 Array
.prototype.push
.apply(scopeDefinitions
, definitions
);
89 Array
.prototype.push
.apply(symbols
, definitions
);
90 Array
.prototype.push
.apply(symbols
, references
);
92 scope
.references
.forEach(function (reference
) {
93 var range
= reference
.identifier
.range
;
94 if (reference
.resolved
|| isDefined(scopeDefinitions
, range
)) {
97 // Handle global references.
106 comments
= ast
.comments
107 .map(function (comment
) {
108 var range
= comment
.range
;
119 .map(function (token
) {
120 // Emacs starts counting from 1.