]>
code.delx.au - gnu-emacs-elpa/blob - scopifier.js
3 var escope
= require('./lib/escope'),
4 esprima
= require('./lib/esprima');
6 // Given code, returns an array of tokens for context-coloring.
7 module
.exports = function (code
) {
26 // Gracefully handle parse errors by doing nothing.
28 ast
= esprima
.parse(code
, {
32 analyzedScopes
= escope
.analyze(ast
).scopes
;
40 for (i
= 0; i
< analyzedScopes
.length
; i
+= 1) {
41 scope
= analyzedScopes
[i
];
42 // Having its level set implies it was already annotated.
43 if (scope
.level
=== undefined) {
45 if (scope
.upper
.functionExpressionScope
) {
46 // Pretend function expression scope doesn't exist.
47 scope
.level
= scope
.upper
.level
;
48 scope
.variables
= scope
.upper
.variables
.concat(scope
.variables
);
50 scope
.level
= scope
.upper
.level
+ 1;
56 // We've only given the scope a level for posterity's sake. We're
58 if (!scope
.functionExpressionScope
) {
59 range
= scope
.block
.range
;
65 definitionsIndex
= tokens
.length
;
67 for (j
= 0; j
< scope
.variables
.length
; j
+= 1) {
68 variable
= scope
.variables
[j
];
69 definitionsCount
+= variable
.defs
.length
;
70 for (k
= 0; k
< variable
.defs
.length
; k
+= 1) {
71 definition
= variable
.defs
[k
];
72 range
= definition
.name
.range
;
80 for (j
= 0; j
< scope
.references
.length
; j
+= 1) {
81 reference
= scope
.references
[j
];
82 range
= reference
.identifier
.range
;
84 // Determine if a definition already exists for the
85 // range. (escope detects variables twice if they are
86 // declared and initialized simultaneously; this filters
88 for (k
= 0; k
< definitionsCount
; k
+= 1) {
89 pointer
= definitionsIndex
+ (k
* 3);
90 if (tokens
[pointer
] === range
[0] + 1 &&
91 tokens
[pointer
+ 1] === range
[1] + 1) {
98 // Handle global references too.
101 reference
.resolved
? reference
.resolved
.scope
.level
: 0
109 for (i
= 0; i
< ast
.comments
.length
; i
+= 1) {
110 comment
= ast
.comments
[i
];
111 range
= comment
.range
;
119 return scopes
.concat(tokens
);