all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
blob fd3549ad1cf06710c9d2e9f7fd5c8885e4501c10 4568 bytes (raw)
name: packages/context-coloring/languages/javascript/scopifier.js 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
 
// Copyright (C) 2014-2015  Free Software Foundation, Inc.

// This file is part of GNU Emacs.

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

'use strict';

var escope = require('./libraries/escope'),
    esprima = require('./libraries/esprima');

// Given code, returns an array of tokens for context-coloring.
function scopifier(code) {

    var analyzedScopes,
        ast,
        definition,
        definitionsCount,
        definitionsIndex,
        i,
        isDefined,
        j,
        k,
        pointer,
        range,
        reference,
        scope,
        scopes,
        tokens,
        variable;

    // Strip BOM.
    code = code.replace(/^\ufeff/g, '');

    // Gracefully handle parse errors by doing nothing.
    try {
        ast = esprima.parse(code, {
            range: true
        });
        analyzedScopes = escope.analyze(ast).scopes;
    } catch (error) {
        process.exit(1);
    }

    scopes = [];
    tokens = [];
    for (i = 0; i < analyzedScopes.length; i += 1) {
        scope = analyzedScopes[i];
        // Having its level set implies it was already annotated.
        if (scope.level === undefined) {
            if (scope.upper) {
                if (scope.upper.functionExpressionScope) {
                    // Pretend function expression scope doesn't exist.
                    scope.level = scope.upper.level;
                    scope.variables = scope.upper.variables.concat(scope.variables);
                } else {
                    scope.level = scope.upper.level + 1;
                }
            } else {
                // Base case.
                scope.level = 0;
            }
            // We've only given the scope a level for posterity's sake.  We're
            // done now.
            if (!scope.functionExpressionScope) {
                range = scope.block.range;
                scopes.push(
                    range[0] + 1,
                    range[1] + 1,
                    scope.level
                );
                definitionsIndex = tokens.length;
                definitionsCount = 0;
                for (j = 0; j < scope.variables.length; j += 1) {
                    variable = scope.variables[j];
                    definitionsCount += variable.defs.length;
                    for (k = 0; k < variable.defs.length; k += 1) {
                        definition = variable.defs[k];
                        range = definition.name.range;
                        tokens.push(
                            range[0] + 1,
                            range[1] + 1,
                            scope.level
                        );
                    }
                }
                for (j = 0; j < scope.references.length; j += 1) {
                    reference = scope.references[j];
                    range = reference.identifier.range;
                    isDefined = false;
                    // Determine if a definition already exists for the range.
                    // (escope detects variables twice if they are declared and
                    // initialized simultaneously; this filters them.)
                    for (k = 0; k < definitionsCount; k += 1) {
                        pointer = definitionsIndex + (k * 3);
                        if (tokens[pointer] === range[0] + 1 &&
                                tokens[pointer + 1] === range[1] + 1) {
                            isDefined = true;
                            break;
                        }
                    }
                    if (!isDefined) {
                        tokens.push(
                            // Handle global references too.
                            range[0] + 1,
                            range[1] + 1,
                            reference.resolved ? reference.resolved.scope.level : 0
                        );
                    }
                }
            }
        }
    }

    return scopes.concat(tokens);
}

module.exports = scopifier;

debug log:

solving fd3549a ...
found fd3549a in https://yhetil.org/emacs/CAGiE8Az6kAQTNuhrZO_dGB1O9hOMqeSbxMOH0bG+RDLPUY0z=A@mail.gmail.com/

applying [1/1] https://yhetil.org/emacs/CAGiE8Az6kAQTNuhrZO_dGB1O9hOMqeSbxMOH0bG+RDLPUY0z=A@mail.gmail.com/
diff --git a/packages/context-coloring/languages/javascript/scopifier.js b/packages/context-coloring/languages/javascript/scopifier.js
new file mode 100644
index 0000000..fd3549a

Checking patch packages/context-coloring/languages/javascript/scopifier.js...
Applied patch packages/context-coloring/languages/javascript/scopifier.js cleanly.

index at:
100644 fd3549ad1cf06710c9d2e9f7fd5c8885e4501c10	packages/context-coloring/languages/javascript/scopifier.js

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.