UNPKG

3.61 kBJavaScriptView Raw
1/**
2 * @fileoverview The event generator for comments.
3 * @author Toru Nagashima
4 */
5
6"use strict";
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 */
21function 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 */
42function 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 */
56function 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 */
77function CommentEventGenerator(originalEventGenerator, sourceCode) {
78 this.original = originalEventGenerator;
79 this.emitter = originalEventGenerator.emitter;
80 this.sourceCode = sourceCode;
81 this.commentLocsEnter = [];
82 this.commentLocsExit = [];
83}
84
85CommentEventGenerator.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
115module.exports = CommentEventGenerator;