-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathparser.js
102 lines (85 loc) · 2.53 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
let AnnotationsApi = require('./annotation').default;
let ScssCommentParser = require('scss-comment-parser');
let through = require('through2');
let concat = require('concat-stream');
let path = require('path');
let utils = require('./utils');
let errors = require('./errors');
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) {
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 = utils.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;
}
}