1 | 'use strict';
|
2 |
|
3 | var uniq = require('lodash/uniq');
|
4 | var uniqWith = require('lodash/uniqWith');
|
5 |
|
6 | var parsersDb = {
|
7 | '.bash': { parserName: 'coffeeParser' },
|
8 | '.c': { parserName: 'defaultParser' },
|
9 | '.cjsx': { parserName: 'coffeeParser' },
|
10 | '.coffee': { parserName: 'coffeeParser' },
|
11 | '.cpp': { parserName: 'defaultParser' },
|
12 | '.cr': { parserName: 'coffeeParser' },
|
13 | '.cs': { parserName: 'defaultParser' },
|
14 | '.cson': { parserName: 'coffeeParser' },
|
15 | '.css': { parserName: 'defaultParser' },
|
16 | '.ejs': { parserName: 'ejsParser' },
|
17 | '.erb': { parserName: 'ejsParser' },
|
18 | '.erl': { parserName: 'erlangParser' },
|
19 | '.es': { parserName: 'defaultParser' },
|
20 | '.es6': { parserName: 'defaultParser' },
|
21 | '.go': { parserName: 'defaultParser' },
|
22 | '.h': { parserName: 'defaultParser' },
|
23 | '.haml': { parserName: 'hamlParser' },
|
24 | '.handlebars': { parserName: 'hbsParser' },
|
25 | '.hbs': { parserName: 'hbsParser' },
|
26 | '.hgn': { parserName: 'hbsParser' },
|
27 | '.hogan': { parserName: 'hbsParser' },
|
28 | '.hrl': { parserName: 'erlangParser' },
|
29 | '.hs': { parserName: 'haskellParser' },
|
30 | '.htm': { parserName: 'twigParser' },
|
31 | '.html': { parserName: 'twigParser' },
|
32 | '.jade': { parserName: 'jadeParser' },
|
33 | '.java': { parserName: 'defaultParser' },
|
34 | '.kt': { parserName: 'defaultParser' },
|
35 | '.js': { parserName: 'defaultParser' },
|
36 | '.jsx': { parserName: 'defaultParser' },
|
37 | '.less': { parserName: 'defaultParser' },
|
38 | '.m': { parserName: 'defaultParser' },
|
39 | '.mm': { parserName: 'defaultParser' },
|
40 | '.mustache': { parserName: 'hbsParser' },
|
41 | '.njk': { parserName: 'twigParser' },
|
42 | '.pas': { parserName: 'pascalParser' },
|
43 | '.php': { parserName: 'defaultParser', includedFiles: ['.html', '.js', '.css'] },
|
44 | '.pl': { parserName: 'coffeeParser' },
|
45 | '.pm': { parserName: 'coffeeParser' },
|
46 | '.pug': { parserName: 'jadeParser' },
|
47 | '.py': { parserName: 'pythonParser' },
|
48 | '.rb': { parserName: 'coffeeParser' },
|
49 | '.sass': { parserName: 'defaultParser' },
|
50 | '.scala': { parserName: 'defaultParser' },
|
51 | '.scss': { parserName: 'defaultParser' },
|
52 | '.sh': { parserName: 'coffeeParser' },
|
53 | '.sql': { parserName: ['defaultParser', 'haskellParser'] },
|
54 | '.ss': { parserName: 'ssParser' },
|
55 | '.styl': { parserName: 'defaultParser' },
|
56 | '.swift': { parserName: 'defaultParser' },
|
57 | '.ts': { parserName: 'defaultParser' },
|
58 | '.tsx': { parserName: 'defaultParser' },
|
59 | '.twig': { parserName: 'twigParser' },
|
60 | '.vue': { parserName: 'twigParser', includedFiles: ['.html', '.js', '.css'] },
|
61 | '.yaml': { parserName: 'coffeeParser', includedFiles: ['.yml'] },
|
62 | '.zsh': { parserName: 'coffeeParser' },
|
63 | };
|
64 |
|
65 |
|
66 | function associateExtWithParser(parsers) {
|
67 | var keys = Object.keys(parsers);
|
68 | if (keys.length === 0) {
|
69 | return;
|
70 | }
|
71 | keys.forEach(function (ext) {
|
72 | if (ext.length <= 1 || ext[0] !== '.') {
|
73 | throw new Error('Cannot register extension: invalid extension ' + ext);
|
74 | }
|
75 | var parser = parsers[ext];
|
76 | if (!parser || !parser.parserName) {
|
77 | throw new Error('Cannot register extension: parser name missing.');
|
78 | }
|
79 | });
|
80 |
|
81 |
|
82 | Object.assign(parsersDb, parsers);
|
83 | }
|
84 |
|
85 | function isExtSupported(ext) {
|
86 | return Boolean(parsersDb[ext]);
|
87 | }
|
88 |
|
89 | function parse(options) {
|
90 | var ext = options.ext;
|
91 | var content = options.content;
|
92 | var fileName = options.fileName;
|
93 | var customTags = options.customTags;
|
94 | var withInlineFiles = options.withInlineFiles || false;
|
95 | var associateParser = options.associateParser || {};
|
96 |
|
97 |
|
98 | associateExtWithParser(associateParser);
|
99 |
|
100 | if (!isExtSupported(ext)) {
|
101 | throw new Error('extension ' + ext + ' is not supported.');
|
102 | }
|
103 | if (customTags && !Array.isArray(customTags)) {
|
104 | throw new TypeError('`customTags` must be an array');
|
105 | }
|
106 | var parseOptions = {
|
107 | customTags: customTags
|
108 | };
|
109 | var originalParser = parsersDb[ext];
|
110 | var parsers = [].concat(originalParser.parserName);
|
111 |
|
112 | var includedFiles = originalParser.includedFiles || [];
|
113 | if (withInlineFiles) {
|
114 | includedFiles.forEach(function (ext) {
|
115 | parsers.push(parsersDb[ext].parserName);
|
116 | });
|
117 | parsers = uniq(parsers);
|
118 | }
|
119 |
|
120 | var parsed = parsers
|
121 | .map(function (parser) {
|
122 | var parserFactory = require('./parsers/' + parser);
|
123 | return parserFactory(parseOptions)(content, fileName);
|
124 | })
|
125 | .reduce(function (items, item) {
|
126 |
|
127 | return items.concat(item);
|
128 | }, [])
|
129 | .sort(function (item1, item2) {
|
130 | return item1.line - item2.line;
|
131 | });
|
132 |
|
133 | return uniqWith(parsed, function (a, b) {
|
134 | return a.line === b.line
|
135 | && a.kind === b.kind
|
136 | && a.text === b.text;
|
137 | });
|
138 | }
|
139 |
|
140 |
|
141 | function parseLegacy(ext, content, fileName, customTags, withInlineFiles) {
|
142 | return parse({
|
143 | ext: ext,
|
144 | content: content,
|
145 | fileName: fileName,
|
146 | customTags: customTags,
|
147 | withInlineFiles: withInlineFiles
|
148 | });
|
149 | }
|
150 |
|
151 | exports.associateExtWithParser = associateExtWithParser;
|
152 | exports.isExtSupported = isExtSupported;
|
153 | exports.parse = parse;
|
154 | exports.parseLegacy = parseLegacy;
|