/ src / token-iterator.js
token-iterator.js
 1  module.exports = class TokenIterator {
 2    constructor(languageMode) {
 3      this.languageMode = languageMode;
 4    }
 5  
 6    reset(line) {
 7      this.line = line;
 8      this.index = null;
 9      this.startColumn = 0;
10      this.endColumn = 0;
11      this.scopes = this.line.openScopes.map(id =>
12        this.languageMode.grammar.scopeForId(id)
13      );
14      this.scopeStarts = this.scopes.slice();
15      this.scopeEnds = [];
16      return this;
17    }
18  
19    next() {
20      const { tags } = this.line;
21  
22      if (this.index != null) {
23        this.startColumn = this.endColumn;
24        this.scopeEnds.length = 0;
25        this.scopeStarts.length = 0;
26        this.index++;
27      } else {
28        this.index = 0;
29      }
30  
31      while (this.index < tags.length) {
32        const tag = tags[this.index];
33        if (tag < 0) {
34          const scope = this.languageMode.grammar.scopeForId(tag);
35          if (tag % 2 === 0) {
36            if (this.scopeStarts[this.scopeStarts.length - 1] === scope) {
37              this.scopeStarts.pop();
38            } else {
39              this.scopeEnds.push(scope);
40            }
41            this.scopes.pop();
42          } else {
43            this.scopeStarts.push(scope);
44            this.scopes.push(scope);
45          }
46          this.index++;
47        } else {
48          this.endColumn += tag;
49          this.text = this.line.text.substring(this.startColumn, this.endColumn);
50          return true;
51        }
52      }
53  
54      return false;
55    }
56  
57    getScopes() {
58      return this.scopes;
59    }
60  
61    getScopeStarts() {
62      return this.scopeStarts;
63    }
64  
65    getScopeEnds() {
66      return this.scopeEnds;
67    }
68  
69    getText() {
70      return this.text;
71    }
72  
73    getBufferStart() {
74      return this.startColumn;
75    }
76  
77    getBufferEnd() {
78      return this.endColumn;
79    }
80  };