-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
118 lines (105 loc) · 2.89 KB
/
index.js
File metadata and controls
118 lines (105 loc) · 2.89 KB
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
const DOUBLE_QUOTE_STRING_STATE = 'double-quote-string-state';
const SINGLE_QUOTE_STRING_STATE = 'single-quote-string-state';
const LINE_COMMENT_STATE = 'line-comment-state';
const BLOCK_COMMENT_STATE = 'block-comment-state';
const ETC_STATE = 'etc-state';
function extractComments(str) {
let state = ETC_STATE;
let i = 0;
const comments = [];
let currentComment = null;
while (i + 1 < str.length) {
if (state === ETC_STATE && str[i] === '/' && str[i + 1] === '/') {
state = LINE_COMMENT_STATE;
currentComment = {
type: 'LineComment',
range: [i]
};
i += 2;
continue;
}
if (state === LINE_COMMENT_STATE && str[i] === '\n') {
state = ETC_STATE;
currentComment.range.push(i);
comments.push(currentComment);
currentComment = null;
i += 1;
continue;
}
if (state === ETC_STATE && str[i] === '/' && str[i + 1] === '*') {
state = BLOCK_COMMENT_STATE;
currentComment = {
type: 'BlockComment',
range: [i]
};
i += 2;
continue;
}
if (state === BLOCK_COMMENT_STATE && str[i] === '*' && str[i + 1] === '/') {
state = ETC_STATE;
currentComment.range.push(i + 2);
comments.push(currentComment);
currentComment = null;
i += 2;
continue;
}
if (state === ETC_STATE && str[i] === '"') {
state = DOUBLE_QUOTE_STRING_STATE;
i += 1;
continue;
}
if (
state === DOUBLE_QUOTE_STRING_STATE &&
str[i] === '"' &&
(str[i - 1] !== '\\' || str[i - 2] === '\\') // ignore previous backslash unless it's escaped
) {
state = ETC_STATE;
i += 1;
continue;
}
if (state === ETC_STATE && str[i] === "'") {
state = SINGLE_QUOTE_STRING_STATE;
i += 1;
continue;
}
if (
state === SINGLE_QUOTE_STRING_STATE &&
str[i] === "'" &&
(str[i - 1] !== '\\' || str[i - 2] === '\\') // ignore previous backslash unless it's escaped
) {
state = ETC_STATE;
i += 1;
continue;
}
i += 1;
}
if (currentComment !== null && currentComment.type === 'LineComment') {
if (str[i] === '\n') {
currentComment.range.push(str.length - 1);
} else {
currentComment.range.push(str.length);
}
comments.push(currentComment);
}
return comments.map((comment) => {
const start = comment.range[0] + 2;
const end =
comment.type === 'LineComment' ? comment.range[1] : comment.range[1] - 2;
const raw = str.slice(start, end);
// removing the leading asterisks from the value is necessary for jsdoc-style comments
let value = raw;
if (comment.type === 'BlockComment') {
value = value
.split('\n')
.map((x) => x.replace(/^\s*\*/, ''))
.join('\n')
.trimRight();
}
return {
...comment,
raw,
value
};
});
}
module.exports = extractComments;