UNPKG

4.98 kBJavaScriptView Raw
1'use strict';
2const path = require('path');
3const dependentFilesUtils = require('./get-dependent-files');
4const change_1 = require('./change');
5const ast_tools_1 = require('../lib/ast-tools');
6/**
7 * Rewrites import module of dependent files when the file is moved.
8 * Also, rewrites export module of related index file of the given file.
9 */
10class ModuleResolver {
11 constructor(oldFilePath, newFilePath, rootPath) {
12 this.oldFilePath = oldFilePath;
13 this.newFilePath = newFilePath;
14 this.rootPath = rootPath;
15 }
16 /**
17 * Changes are applied from the bottom of a file to the top.
18 * An array of Change instances are sorted based upon the order,
19 * then apply() method is called sequentially.
20 *
21 * @param changes {Change []}
22 * @param host {Host}
23 * @return Promise after all apply() method of Change class is called
24 * to all Change instances sequentially.
25 */
26 applySortedChangePromise(changes, host = ast_tools_1.NodeHost) {
27 return changes
28 .sort((currentChange, nextChange) => nextChange.order - currentChange.order)
29 .reduce((newChange, change) => newChange.then(() => change.apply(host)), Promise.resolve());
30 }
31 /**
32 * Assesses the import specifier and determines if it is a relative import.
33 *
34 * @return {boolean} boolean value if the import specifier is a relative import.
35 */
36 isRelativeImport(importClause) {
37 let singleSlash = importClause.specifierText.charAt(0) === '/';
38 let currentDirSyntax = importClause.specifierText.slice(0, 2) === './';
39 let parentDirSyntax = importClause.specifierText.slice(0, 3) === '../';
40 return singleSlash || currentDirSyntax || parentDirSyntax;
41 }
42 /**
43 * Rewrites the import specifiers of all the dependent files (cases for no index file).
44 *
45 * @todo Implement the logic for rewriting imports of the dependent files when the file
46 * being moved has index file in its old path and/or in its new path.
47 *
48 * @return {Promise<Change[]>}
49 */
50 resolveDependentFiles() {
51 return dependentFilesUtils.getDependentFiles(this.oldFilePath, this.rootPath)
52 .then((files) => {
53 let changes = [];
54 let fileBaseName = path.basename(this.oldFilePath, '.ts');
55 // Filter out the spec file associated with to-be-promoted component unit.
56 let relavantFiles = Object.keys(files).filter((file) => {
57 if (path.extname(path.basename(file, '.ts')) === '.spec') {
58 return path.basename(path.basename(file, '.ts'), '.spec') !== fileBaseName;
59 }
60 else {
61 return true;
62 }
63 });
64 relavantFiles.forEach(file => {
65 let tempChanges = files[file]
66 .map(specifier => {
67 let componentName = path.basename(this.oldFilePath, '.ts');
68 let fileDir = path.dirname(file);
69 let changeText = path.relative(fileDir, path.join(this.newFilePath, componentName));
70 if (changeText.length > 0 && changeText.charAt(0) !== '.') {
71 changeText = `.${path.sep}${changeText}`;
72 }
73 ;
74 let position = specifier.end - specifier.specifierText.length;
75 return new change_1.ReplaceChange(file, position - 1, specifier.specifierText, changeText);
76 });
77 changes = changes.concat(tempChanges);
78 });
79 return changes;
80 });
81 }
82 /**
83 * Rewrites the file's own relative imports after it has been moved to new path.
84 *
85 * @return {Promise<Change[]>}
86 */
87 resolveOwnImports() {
88 return dependentFilesUtils.createTsSourceFile(this.oldFilePath)
89 .then((tsFile) => dependentFilesUtils.getImportClauses(tsFile))
90 .then(moduleSpecifiers => {
91 let changes = moduleSpecifiers
92 .filter(importClause => this.isRelativeImport(importClause))
93 .map(specifier => {
94 let specifierText = specifier.specifierText;
95 let moduleAbsolutePath = path.resolve(path.dirname(this.oldFilePath), specifierText);
96 let changeText = path.relative(this.newFilePath, moduleAbsolutePath);
97 if (changeText.length > 0 && changeText.charAt(0) !== '.') {
98 changeText = `.${path.sep}${changeText}`;
99 }
100 let position = specifier.end - specifier.specifierText.length;
101 return new change_1.ReplaceChange(this.oldFilePath, position - 1, specifierText, changeText);
102 });
103 return changes;
104 });
105 }
106}
107exports.ModuleResolver = ModuleResolver;
108//# sourceMappingURL=/Users/hansl/Sources/angular-cli/packages/@angular/cli/utilities/module-resolver.js.map
\No newline at end of file