]>
code.delx.au - gnu-emacs-elpa/blob - scopifier.js
3 var escope
= require('escope'),
4 esprima
= require('esprima'),
6 // Given an array of definitions, determines if a definition already exists
7 // for a given range. (escope detects variables twice if they are declared
8 // and initialized simultaneously; this filters them.)
9 isDefined = function (definitions
, range
) {
10 return definitions
.some(function (definition
) {
11 // Check for identical definitions.
12 return definition
[1] === range
[0] &&
13 definition
[2] === range
[1];
17 // Given code, returns an array of `[level, start, end]' tokens for
19 module
.exports = function (code
) {
27 // Gracefully handle parse errors by doing nothing.
29 ast
= esprima
.parse(code
, {
33 analyzedScopes
= escope
.analyze(ast
).scopes
;
38 analyzedScopes
.forEach(function (scope
) {
41 if (scope
.level
!== undefined) {
42 // Having its level set implies it was already annotated.
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;
57 if (scope
.functionExpressionScope
) {
58 // We've only given the scope a level for posterity's sake. We're
62 scopes
= scopes
.concat([[
67 definitions
= scope
.variables
.reduce(function (definitions
, variable
) {
68 var mappedDefinitions
= variable
.defs
.map(function (definition
) {
69 var range
= definition
.name
.range
;
76 return definitions
.concat(mappedDefinitions
);
78 references
= scope
.references
.reduce(function (references
, reference
) {
79 var range
= reference
.identifier
.range
;
80 if (isDefined(definitions
, range
)) {
83 return references
.concat([[
84 // Handle global references too.
85 reference
.resolved
? reference
.resolved
.scope
.level
: 0,
90 symbols
= symbols
.concat(definitions
).concat(references
);
93 comments
= ast
.comments
94 .map(function (comment
) {
95 var range
= comment
.range
;
106 .map(function (token
) {
107 // Emacs starts counting from 1.