1 | /**
|
2 | * @fileoverview The event generator for comments.
|
3 | * @author Toru Nagashima
|
4 | */
|
5 |
|
6 | ;
|
7 |
|
8 | //------------------------------------------------------------------------------
|
9 | // Helpers
|
10 | //------------------------------------------------------------------------------
|
11 |
|
12 | /**
|
13 | * Check collection of comments to prevent double event for comment as
|
14 | * leading and trailing, then emit event if passing
|
15 | * @param {ASTNode[]} comments - Collection of comment nodes
|
16 | * @param {EventEmitter} emitter - The event emitter which is the destination of events.
|
17 | * @param {Object[]} locs - List of locations of previous comment nodes
|
18 | * @param {string} eventName - Event name postfix
|
19 | * @returns {void}
|
20 | */
|
21 | function emitComments(comments, emitter, locs, eventName) {
|
22 | if (comments.length > 0) {
|
23 | comments.forEach(function(node) {
|
24 | const index = locs.indexOf(node.loc);
|
25 |
|
26 | if (index >= 0) {
|
27 | locs.splice(index, 1);
|
28 | } else {
|
29 | locs.push(node.loc);
|
30 | emitter.emit(node.type + eventName, node);
|
31 | }
|
32 | });
|
33 | }
|
34 | }
|
35 |
|
36 | /**
|
37 | * Shortcut to check and emit enter of comment nodes
|
38 | * @param {CommentEventGenerator} generator - A generator to emit.
|
39 | * @param {ASTNode[]} comments - Collection of comment nodes
|
40 | * @returns {void}
|
41 | */
|
42 | function emitCommentsEnter(generator, comments) {
|
43 | emitComments(
|
44 | comments,
|
45 | generator.emitter,
|
46 | generator.commentLocsEnter,
|
47 | "Comment");
|
48 | }
|
49 |
|
50 | /**
|
51 | * Shortcut to check and emit exit of comment nodes
|
52 | * @param {CommentEventGenerator} generator - A generator to emit.
|
53 | * @param {ASTNode[]} comments Collection of comment nodes
|
54 | * @returns {void}
|
55 | */
|
56 | function emitCommentsExit(generator, comments) {
|
57 | emitComments(
|
58 | comments,
|
59 | generator.emitter,
|
60 | generator.commentLocsExit,
|
61 | "Comment:exit");
|
62 | }
|
63 |
|
64 | //------------------------------------------------------------------------------
|
65 | // Public Interface
|
66 | //------------------------------------------------------------------------------
|
67 |
|
68 | /**
|
69 | * The event generator for comments.
|
70 | * This is the decorator pattern.
|
71 | * This generates events of comments before/after events which are generated the original generator.
|
72 | *
|
73 | * @param {EventGenerator} originalEventGenerator - An event generator which is the decoration target.
|
74 | * @param {SourceCode} sourceCode - A source code which has comments.
|
75 | * @returns {CommentEventGenerator} new instance.
|
76 | */
|
77 | function CommentEventGenerator(originalEventGenerator, sourceCode) {
|
78 | this.original = originalEventGenerator;
|
79 | this.emitter = originalEventGenerator.emitter;
|
80 | this.sourceCode = sourceCode;
|
81 | this.commentLocsEnter = [];
|
82 | this.commentLocsExit = [];
|
83 | }
|
84 |
|
85 | CommentEventGenerator.prototype = {
|
86 | constructor: CommentEventGenerator,
|
87 |
|
88 | /**
|
89 | * Emits an event of entering comments.
|
90 | * @param {ASTNode} node - A node which was entered.
|
91 | * @returns {void}
|
92 | */
|
93 | enterNode: function enterNode(node) {
|
94 | const comments = this.sourceCode.getComments(node);
|
95 |
|
96 | emitCommentsEnter(this, comments.leading);
|
97 | this.original.enterNode(node);
|
98 | emitCommentsEnter(this, comments.trailing);
|
99 | },
|
100 |
|
101 | /**
|
102 | * Emits an event of leaving comments.
|
103 | * @param {ASTNode} node - A node which was left.
|
104 | * @returns {void}
|
105 | */
|
106 | leaveNode: function leaveNode(node) {
|
107 | const comments = this.sourceCode.getComments(node);
|
108 |
|
109 | emitCommentsExit(this, comments.trailing);
|
110 | this.original.leaveNode(node);
|
111 | emitCommentsExit(this, comments.leading);
|
112 | }
|
113 | };
|
114 |
|
115 | module.exports = CommentEventGenerator;
|