source: trip-planner-front/node_modules/@ngtools/webpack/src/transformers/elide_imports.js@ 6a3a178

Last change on this file since 6a3a178 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 7.7 KB
Line 
1"use strict";
2/**
3 * @license
4 * Copyright Google LLC All Rights Reserved.
5 *
6 * Use of this source code is governed by an MIT-style license that can be
7 * found in the LICENSE file at https://angular.io/license
8 */
9var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10 if (k2 === undefined) k2 = k;
11 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
12}) : (function(o, m, k, k2) {
13 if (k2 === undefined) k2 = k;
14 o[k2] = m[k];
15}));
16var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17 Object.defineProperty(o, "default", { enumerable: true, value: v });
18}) : function(o, v) {
19 o["default"] = v;
20});
21var __importStar = (this && this.__importStar) || function (mod) {
22 if (mod && mod.__esModule) return mod;
23 var result = {};
24 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
25 __setModuleDefault(result, mod);
26 return result;
27};
28Object.defineProperty(exports, "__esModule", { value: true });
29exports.elideImports = void 0;
30const ts = __importStar(require("typescript"));
31// Remove imports for which all identifiers have been removed.
32// Needs type checker, and works even if it's not the first transformer.
33// Works by removing imports for symbols whose identifiers have all been removed.
34// Doesn't use the `symbol.declarations` because that previous transforms might have removed nodes
35// but the type checker doesn't know.
36// See https://github.com/Microsoft/TypeScript/issues/17552 for more information.
37function elideImports(sourceFile, removedNodes, getTypeChecker, compilerOptions) {
38 const importNodeRemovals = new Set();
39 if (removedNodes.length === 0) {
40 return importNodeRemovals;
41 }
42 const typeChecker = getTypeChecker();
43 // Collect all imports and used identifiers
44 const usedSymbols = new Set();
45 const imports = [];
46 ts.forEachChild(sourceFile, function visit(node) {
47 var _a, _b, _c, _d, _e;
48 // Skip removed nodes.
49 if (removedNodes.includes(node)) {
50 return;
51 }
52 // Consider types for 'implements' as unused.
53 // A HeritageClause token can also be an 'AbstractKeyword'
54 // which in that case we should not elide the import.
55 if (ts.isHeritageClause(node) && node.token === ts.SyntaxKind.ImplementsKeyword) {
56 return;
57 }
58 // Record import and skip
59 if (ts.isImportDeclaration(node)) {
60 if (!((_a = node.importClause) === null || _a === void 0 ? void 0 : _a.isTypeOnly)) {
61 imports.push(node);
62 }
63 return;
64 }
65 let symbol;
66 if (ts.isTypeReferenceNode(node)) {
67 if (!compilerOptions.emitDecoratorMetadata) {
68 // Skip and mark as unused if emitDecoratorMetadata is disabled.
69 return;
70 }
71 const parent = node.parent;
72 let isTypeReferenceForDecoratoredNode = false;
73 switch (parent.kind) {
74 case ts.SyntaxKind.GetAccessor:
75 case ts.SyntaxKind.PropertyDeclaration:
76 case ts.SyntaxKind.MethodDeclaration:
77 isTypeReferenceForDecoratoredNode = !!((_b = parent.decorators) === null || _b === void 0 ? void 0 : _b.length);
78 break;
79 case ts.SyntaxKind.Parameter:
80 // - A constructor parameter can be decorated or the class itself is decorated.
81 // - The parent of the parameter is decorated example a method declaration or a set accessor.
82 // In all cases we need the type reference not to be elided.
83 isTypeReferenceForDecoratoredNode = !!(((_c = parent.decorators) === null || _c === void 0 ? void 0 : _c.length) ||
84 (ts.isSetAccessor(parent.parent) && !!((_d = parent.parent.decorators) === null || _d === void 0 ? void 0 : _d.length)) ||
85 (ts.isConstructorDeclaration(parent.parent) &&
86 !!((_e = parent.parent.parent.decorators) === null || _e === void 0 ? void 0 : _e.length)));
87 break;
88 }
89 if (isTypeReferenceForDecoratoredNode) {
90 symbol = typeChecker.getSymbolAtLocation(node.typeName);
91 }
92 }
93 else {
94 switch (node.kind) {
95 case ts.SyntaxKind.Identifier:
96 const parent = node.parent;
97 if (parent && ts.isShorthandPropertyAssignment(parent)) {
98 const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(parent);
99 if (shorthandSymbol) {
100 symbol = shorthandSymbol;
101 }
102 }
103 else {
104 symbol = typeChecker.getSymbolAtLocation(node);
105 }
106 break;
107 case ts.SyntaxKind.ExportSpecifier:
108 symbol = typeChecker.getExportSpecifierLocalTargetSymbol(node);
109 break;
110 case ts.SyntaxKind.ShorthandPropertyAssignment:
111 symbol = typeChecker.getShorthandAssignmentValueSymbol(node);
112 break;
113 }
114 }
115 if (symbol) {
116 usedSymbols.add(symbol);
117 }
118 ts.forEachChild(node, visit);
119 });
120 if (imports.length === 0) {
121 return importNodeRemovals;
122 }
123 const isUnused = (node) => {
124 // Do not remove JSX factory imports
125 if (node.text === compilerOptions.jsxFactory) {
126 return false;
127 }
128 const symbol = typeChecker.getSymbolAtLocation(node);
129 return symbol && !usedSymbols.has(symbol);
130 };
131 for (const node of imports) {
132 if (!node.importClause) {
133 // "import 'abc';"
134 continue;
135 }
136 const namedBindings = node.importClause.namedBindings;
137 if (namedBindings && ts.isNamespaceImport(namedBindings)) {
138 // "import * as XYZ from 'abc';"
139 if (isUnused(namedBindings.name)) {
140 importNodeRemovals.add(node);
141 }
142 }
143 else {
144 const specifierNodeRemovals = [];
145 let clausesCount = 0;
146 // "import { XYZ, ... } from 'abc';"
147 if (namedBindings && ts.isNamedImports(namedBindings)) {
148 let removedClausesCount = 0;
149 clausesCount += namedBindings.elements.length;
150 for (const specifier of namedBindings.elements) {
151 if (isUnused(specifier.name)) {
152 removedClausesCount++;
153 // in case we don't have any more namedImports we should remove the parent ie the {}
154 const nodeToRemove = clausesCount === removedClausesCount ? specifier.parent : specifier;
155 specifierNodeRemovals.push(nodeToRemove);
156 }
157 }
158 }
159 // "import XYZ from 'abc';"
160 if (node.importClause.name) {
161 clausesCount++;
162 if (isUnused(node.importClause.name)) {
163 specifierNodeRemovals.push(node.importClause.name);
164 }
165 }
166 if (specifierNodeRemovals.length === clausesCount) {
167 importNodeRemovals.add(node);
168 }
169 else {
170 for (const specifierNodeRemoval of specifierNodeRemovals) {
171 importNodeRemovals.add(specifierNodeRemoval);
172 }
173 }
174 }
175 }
176 return importNodeRemovals;
177}
178exports.elideImports = elideImports;
Note: See TracBrowser for help on using the repository browser.