UNPKG

2.24 kBJavaScriptView Raw
1const falafel = require('falafel')
2const debug = require('debug')('comment-value')
3
4function instrumentSource (source, filename) {
5 // TODO handle multiple files by making this object global
6 // and avoiding overwriting it
7 const __instrumenter = global.__instrumenter || {
8 comments: []
9 }
10
11 const endsBeforeInstrumentedComment = node =>
12 __instrumenter.comments.some(c => c.start === node.end + 1)
13 const findComment = node =>
14 __instrumenter.comments.find(c => c.start === node.end + 1)
15
16 function instrument (node) {
17 // TODO can also handle individual value
18 if (node.type === 'ExpressionStatement' ||
19 node.type === 'Identifier') {
20 // console.log(node.type, node.end, node.source())
21 if (endsBeforeInstrumentedComment(node)) {
22 // console.log('need to instrument!')
23 const comment = findComment(node)
24 // console.log(comment)
25 const reference = 'global.__instrumenter.comments[' + comment.index + '].value'
26 const store = reference + ' = ' + node.source()
27 const storeAndReturn = ';(function () {' + store + '; return ' + reference + '}())'
28 node.update(storeAndReturn)
29 }
30 }
31 }
32
33 const isInstrumentComment = s => s.startsWith('>')
34
35 const parserOptions = {
36 locations: true,
37 onComment (block, text, start, end, from, to) {
38 if (block) {
39 return
40 }
41 if (!isInstrumentComment(text)) {
42 return
43 }
44 // console.log('comment', arguments)
45 const index = __instrumenter.comments.length
46 __instrumenter.comments.push({
47 value: undefined,
48 start: start,
49 text: text,
50 index: index,
51 from: from,
52 to: to,
53 filename: filename
54 })
55 }
56 }
57 const output = falafel(source, parserOptions, instrument)
58 debug('instrumented for %d comments', __instrumenter.comments.length)
59 // console.log(__instrumenter.comments)
60 const preamble = 'if (!global.__instrumenter) {global.__instrumenter=' +
61 JSON.stringify(__instrumenter, null, 2) + '}\n'
62 // console.log(preamble)
63 // console.log('output source\n' + output)
64
65 const sep = ';\n'
66 const instrumented = preamble + sep + output
67 return instrumented
68}
69
70module.exports = instrumentSource