]>
code.delx.au - gnu-emacs-elpa/blob - scopifier.js
167e8998a4117b5f6d7a93b51f3ab334b1c9b453
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
) {
31 // Gracefully handle parse errors by doing nothing.
33 ast
= esprima
.parse(code
, {
37 analyzedScopes
= escope
.analyze(ast
).scopes
;
45 for (i
= 0; i
< analyzedScopes
.length
; i
+= 1) {
46 scope
= analyzedScopes
[i
];
47 // Having its level set implies it was already annotated.
48 if (scope
.level
=== undefined) {
50 if (scope
.upper
.functionExpressionScope
) {
51 // Pretend function expression scope doesn't exist.
52 scope
.level
= scope
.upper
.level
;
53 scope
.variables
= scope
.upper
.variables
.concat(scope
.variables
);
55 scope
.level
= scope
.upper
.level
+ 1;
61 // We've only given the scope a level for posterity's sake. We're
63 if (!scope
.functionExpressionScope
) {
64 range
= scope
.block
.range
;
71 definitionsIndex
= tokens
.length
;
73 for (j
= 0; j
< scope
.variables
.length
; j
+= 1) {
74 variable
= scope
.variables
[j
];
75 definitionsCount
+= variable
.defs
.length
;
76 for (k
= 0; k
< variable
.defs
.length
; k
+= 1) {
77 definition
= variable
.defs
[k
];
78 range
= definition
.name
.range
;
87 for (j
= 0; j
< scope
.references
.length
; j
+= 1) {
88 reference
= scope
.references
[j
];
89 range
= reference
.identifier
.range
;
91 // Determine if a definition already exists for the
92 // range. (escope detects variables twice if they are
93 // declared and initialized simultaneously; this filters
95 for (k
= 0; k
< definitionsCount
; k
+= 1) {
96 pointer
= definitionsIndex
+ (k
* 4);
97 if (tokens
[pointer
] === range
[0] + 1 &&
98 tokens
[pointer
+ 1] === range
[1] + 1) {
105 // Handle global references too.
108 reference
.resolved
? reference
.resolved
.scope
.level
: 0,
109 reference
.__maybeImplicitGlobal
? bold
: normal
117 for (i
= 0; i
< ast
.comments
.length
; i
+= 1) {
118 comment
= ast
.comments
[i
];
119 range
= comment
.range
;
128 return scopes
.concat(tokens
);