]>
code.delx.au - gnu-emacs-elpa/blob - scopifier.js
3 var escope
= require('escope'),
4 esprima
= require('esprima'),
10 // Given code, returns an array of `[start, end, level, style]' tokens for
12 module
.exports = function (code
) {
30 // Gracefully handle parse errors by doing nothing.
32 ast
= esprima
.parse(code
, {
36 analyzedScopes
= escope
.analyze(ast
).scopes
;
44 for (i
= 0; i
< analyzedScopes
.length
; i
+= 1) {
45 scope
= analyzedScopes
[i
];
46 // Having its level set implies it was already annotated.
47 if (scope
.level
=== undefined) {
49 if (scope
.upper
.functionExpressionScope
) {
50 // Pretend function expression scope doesn't exist.
51 scope
.level
= scope
.upper
.level
;
52 scope
.variables
= scope
.upper
.variables
.concat(scope
.variables
);
54 scope
.level
= scope
.upper
.level
+ 1;
60 // We've only given the scope a level for posterity's sake. We're
62 if (!scope
.functionExpressionScope
) {
63 range
= scope
.block
.range
;
70 definitionsIndex
= tokens
.length
;
72 for (j
= 0; j
< scope
.variables
.length
; j
+= 1) {
73 variable
= scope
.variables
[j
];
74 definitionsCount
+= variable
.defs
.length
;
75 for (k
= 0; k
< variable
.defs
.length
; k
+= 1) {
76 definition
= variable
.defs
[k
];
77 range
= definition
.name
.range
;
86 for (j
= 0; j
< scope
.references
.length
; j
+= 1) {
87 reference
= scope
.references
[j
];
88 range
= reference
.identifier
.range
;
90 // Determine if a definition already exists for the
91 // range. (escope detects variables twice if they are
92 // declared and initialized simultaneously; this filters
94 for (k
= 0; k
< definitionsCount
; k
+= 1) {
95 definition
= tokens
[definitionsIndex
+ k
];
96 if (definition
[0] === range
[0] + 1 &&
97 definition
[1] === range
[1] + 1) {
104 // Handle global references too.
107 reference
.resolved
? reference
.resolved
.scope
.level
: 0,
108 reference
.__maybeImplicitGlobal
? bold
: normal
116 for (i
= 0; i
< ast
.comments
.length
; i
+= 1) {
117 comment
= ast
.comments
[i
];
118 range
= comment
.range
;
127 return scopes
.concat(tokens
);