UNPKG

3.85 kBJavaScriptView Raw
1'use strict';
2
3var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
4
5/**
6 * @file: index
7 * @author: Cuttle Cong
8 * @date: 2017/11/29
9 * @description:
10 */
11var getSpecImport = require('./utils/getSpecImport');
12
13var _require = require('../package.json'),
14 symbol = _require.name;
15
16function warn() {
17 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
18 args[_key] = arguments[_key];
19 }
20
21 console.warn.apply(console, [symbol + ' Warn: \n '].concat(args));
22}
23function log() {
24 for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
25 args[_key2] = arguments[_key2];
26 }
27
28 console.log.apply(console, [symbol + ' Log: \n '].concat(args));
29}
30
31var idTraverseObject = {
32 Identifier: function Identifier(path, _ref) {
33 var runtimeData = _ref.runtimeData;
34 var parentPath = path.parentPath;
35 var name = path.node.name;
36 // const ID = 'value';
37
38 if (parentPath.isVariableDeclarator() && parentPath.get('id') === path) {}
39 // { Tabs: 'value' }
40 else if (parentPath.isLabeledStatement() && parentPath.get('label') === path) {}
41 // ref.ID
42 else if (parentPath.isMemberExpression() && parentPath.get('property') === path) {}
43 // class A { ID() {} }
44 else if ((parentPath.isClassProperty() || parentPath.isClassMethod()) && parentPath.get('key') === path) {} else {
45 // used
46 if (runtimeData[name]) {
47 delete runtimeData[name];
48 }
49 }
50 }
51};
52
53var importTraverseObject = _extends({
54 ImportDeclaration: function ImportDeclaration(path, data) {
55 var _data$opts = data.opts,
56 opts = _data$opts === undefined ? {} : _data$opts,
57 runtimeData = data.runtimeData;
58
59
60 var locals = getSpecImport(path, { withPath: true, ignore: opts.ignore });
61 if (locals) {
62 locals.forEach(function (pathData, index, all) {
63 var name = pathData.name;
64 // already existed
65
66 if (runtimeData[name]) {
67 warn('the declare of ', '`' + name + '`', 'is already existed');
68 return;
69 }
70 runtimeData[name] = {
71 parent: path,
72 children: all,
73 data: pathData
74 };
75 });
76
77 path.skip();
78 }
79 }
80}, idTraverseObject);
81
82function handleRemovePath(runtimeData) {
83 var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
84 var _opts$verbose = opts.verbose,
85 verbose = _opts$verbose === undefined ? false : _opts$verbose;
86 /*
87 {
88 parent: path,
89 children: [ { path, name } ],
90 data: { path, name }
91 }
92 */
93
94 var allNames = Object.keys(runtimeData);
95 verbose && log('unused-import-list', allNames);
96 allNames.forEach(function (name) {
97 var _runtimeData$name = runtimeData[name],
98 children = _runtimeData$name.children,
99 data = _runtimeData$name.data,
100 parent = _runtimeData$name.parent;
101
102 var childNames = children.map(function (x) {
103 return x.name;
104 });
105 // every imported identifier is unused
106 if (childNames.every(function (cName) {
107 return allNames.includes(cName);
108 })) {
109 parent.remove();
110 } else {
111 data.path.remove();
112 }
113 });
114}
115
116module.exports = function (babel) {
117 return {
118 pre: function pre(path) {
119 this.runtimeData = {};
120 },
121
122 visitor: {
123 Program: function Program(path, data) {
124 path.traverse(importTraverseObject, {
125 opts: data.opts,
126 runtimeData: this.runtimeData
127 });
128 handleRemovePath(this.runtimeData, data.opts);
129 }
130 },
131 post: function post() {
132 delete this.runtimeData;
133 }
134 };
135};
\No newline at end of file