-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathparser.js
106 lines (87 loc) · 2.52 KB
/
parser.js
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
import { defer } from './utils'
import * as errors from './errors'
import AnnotationsApi from './annotation'
import sorter from './sorter'
import ScssCommentParser from 'scss-comment-parser'
import through from 'through2'
import concat from 'concat-stream'
import path from 'path'
export default class Parser {
constructor (env, additionalAnnotations) {
this.annotations = new AnnotationsApi(env)
this.annotations.addAnnotations(additionalAnnotations)
this.scssParser = new ScssCommentParser(this.annotations.list, env)
this.scssParser.commentParser.on('warning', warning => {
env.emit('warning', new errors.Warning(warning.message))
})
}
parse (code, id) {
return this.scssParser.parse(code, id)
}
/**
* Invoke the `resolve` function of an annotation if present.
* Called with all found annotations except with type "unkown".
*/
postProcess (data) {
data = sorter(data)
Object.keys(this.annotations.list).forEach(key => {
let annotation = this.annotations.list[key]
if (annotation.resolve) {
annotation.resolve(data)
}
})
return data
}
/**
* Return a transform stream meant to be piped in a stream of SCSS
* files. Each file will be passed-through as-is, but they are all
* parsed to generate a SassDoc data array.
*
* The returned stream has an additional `promise` property, containing
* a `Promise` object that will be resolved when the stream is done and
* the data is fulfiled.
*
* @param {Object} parser
* @return {Object}
*/
stream () {
let deferred = defer()
let data = []
let transform = (file, enc, cb) => {
// Pass-through.
cb(null, file)
let parseFile = ({ buf, name, path }) => {
let fileData = this.parse(buf.toString(enc), name)
fileData.forEach(item => {
item.file = {
path,
name,
}
data.push(item)
})
}
if (file.isBuffer()) {
let args = {
buf: file.contents,
name: path.basename(file.relative),
path: file.relative,
}
parseFile(args)
}
if (file.isStream()) {
file.pipe(concat(buf => {
parseFile({ buf })
}))
}
}
let flush = cb => {
data = data.filter(item => item.context.type !== 'unknown')
data = this.postProcess(data)
deferred.resolve(data)
cb()
}
let filter = through.obj(transform, flush)
filter.promise = deferred.promise
return filter
}
}