|
1 | 1 | import { NamedImport } from '../../imports/NamedImport';
|
2 | 2 | import { SymbolSpecifier } from '../../SymbolSpecifier';
|
3 | 3 | import { stringTemplate } from '../../utilities/StringTemplate';
|
4 |
| -import { TypescriptGenerationOptions } from '../TypescriptGenerationOptions'; |
| 4 | +import { TypescriptGenerationOptions, MultiLineImportRule } from '../TypescriptGenerationOptions'; |
5 | 5 | import { generateSymbolSpecifier } from './symbolSpecifier';
|
6 | 6 |
|
7 |
| -const importTemplate = stringTemplate`import ${0} from ${1}`; |
| 7 | +const oneLinerImportTemplate = stringTemplate`import ${0} from ${1}`; |
8 | 8 |
|
9 |
| -const multiLineImport = stringTemplate`import ${3}{ |
| 9 | +const multiLineImportTemplate = stringTemplate`import ${3}{ |
10 | 10 | ${0}${1}
|
11 | 11 | } from ${2}`;
|
12 | 12 |
|
| 13 | +const defaultAliasOnlyMultiLineImportTemplate = stringTemplate`import ${0} |
| 14 | +from ${1}`; |
| 15 | + |
13 | 16 | /**
|
14 | 17 | * Sort function for symbol specifiers. Does sort after the specifiers name (to lowercase).
|
15 | 18 | *
|
@@ -45,34 +48,61 @@ export function generateNamedImport(
|
45 | 48 | stringQuoteStyle,
|
46 | 49 | spaceBraces,
|
47 | 50 | tabSize,
|
| 51 | + wrapMethod, |
48 | 52 | multiLineWrapThreshold,
|
49 | 53 | multiLineTrailingComma,
|
| 54 | + insertSpaces = true, |
50 | 55 | }: TypescriptGenerationOptions,
|
51 | 56 | ): string {
|
52 |
| - const space = spaceBraces ? ' ' : ''; |
53 | 57 | const lib = `${stringQuoteStyle}${imp.libraryName}${stringQuoteStyle}${eol}`;
|
54 |
| - |
55 |
| - const specifiers = imp.specifiers.sort(specifierSort).map(o => generateSymbolSpecifier(o)).join(', '); |
56 |
| - let importSpecifiers = `${space}${specifiers}${space}`; |
57 |
| - if (importSpecifiers.trim().length === 0) { |
58 |
| - importSpecifiers = ' '; |
| 58 | + // const specifiers = imp.specifiers.sort(specifierSort).map(o => generateSymbolSpecifier(o)).join(', '); |
| 59 | + const oneLinerImportStatement = oneLinerImportTemplate(getImportSpecifiers(imp, spaceBraces), lib); |
| 60 | + if (oneLinerImportStatement.length <= multiLineWrapThreshold && |
| 61 | + (wrapMethod !== MultiLineImportRule.strictlyOneImportPerLine || |
| 62 | + imp.specifiers.length <= 1)) { |
| 63 | + return oneLinerImportStatement; |
59 | 64 | }
|
60 |
| - |
61 |
| - const importString = importTemplate( |
62 |
| - getImportSpecifiers(imp, spaceBraces), |
63 |
| - lib, |
64 |
| - ); |
65 |
| - |
66 |
| - if (importString.length > multiLineWrapThreshold) { |
67 |
| - const spacings = Array(tabSize + 1).join(' '); |
68 |
| - return multiLineImport( |
69 |
| - imp.specifiers.sort(specifierSort).map(o => `${spacings}${generateSymbolSpecifier(o)}`).join(',\n'), |
70 |
| - multiLineTrailingComma ? ',' : '', |
71 |
| - `${stringQuoteStyle}${imp.libraryName}${stringQuoteStyle}${eol}`, |
| 65 | + const defaultAliasOnly: boolean = imp.specifiers.length === 0; |
| 66 | + if (defaultAliasOnly) { |
| 67 | + return defaultAliasOnlyMultiLineImportTemplate( |
72 | 68 | imp.defaultAlias ? `${imp.defaultAlias}, ` : '',
|
| 69 | + `${stringQuoteStyle}${imp.libraryName}${stringQuoteStyle}${eol}`, |
73 | 70 | );
|
74 | 71 | }
|
75 |
| - return importString; |
| 72 | + |
| 73 | + const sortedImportSpecifiers: SymbolSpecifier[] = imp.specifiers.sort(specifierSort); |
| 74 | + let importSpecifierStrings: string = ''; |
| 75 | + const indent = insertSpaces ? Array(tabSize + 1).join(' ') : '\t'; |
| 76 | + if (wrapMethod === MultiLineImportRule.strictlyOneImportPerLine || |
| 77 | + wrapMethod === MultiLineImportRule.oneImportPerLineOnlyAfterThreshold) { |
| 78 | + importSpecifierStrings = sortedImportSpecifiers.map(o => `${indent}${generateSymbolSpecifier(o)}`).join(',\n'); |
| 79 | + } else if (wrapMethod === MultiLineImportRule.multipleImportsPerLine) { |
| 80 | + importSpecifierStrings = sortedImportSpecifiers.reduce( |
| 81 | + (acc, curr) => { |
| 82 | + const symbolSpecifier: string = generateSymbolSpecifier(curr); |
| 83 | + // const dist: number = acc.out.length - acc.lastWrapOffset + symbolSpecifier.length; |
| 84 | + const importLines = acc.out.split('\n'); |
| 85 | + const lastImportLine = importLines[importLines.length - 1]; |
| 86 | + const dist: number = lastImportLine.length + `, `.length + symbolSpecifier.length; |
| 87 | + const needsWrap: boolean = dist >= multiLineWrapThreshold; |
| 88 | + return { |
| 89 | + out: acc.out + (needsWrap ? `,\n${indent}` : (acc.out.length ? `, ` : `${indent}`)) + |
| 90 | + symbolSpecifier, |
| 91 | + lastWrapOffset: acc.lastWrapOffset + (needsWrap ? dist : 0), |
| 92 | + }; |
| 93 | + }, |
| 94 | + { |
| 95 | + out: '', |
| 96 | + lastWrapOffset: 0, |
| 97 | + }, |
| 98 | + ).out; |
| 99 | + } |
| 100 | + return multiLineImportTemplate( |
| 101 | + importSpecifierStrings, |
| 102 | + multiLineTrailingComma ? ',' : '', |
| 103 | + `${stringQuoteStyle}${imp.libraryName}${stringQuoteStyle}${eol}`, |
| 104 | + imp.defaultAlias ? `${imp.defaultAlias}, ` : '', |
| 105 | + ); |
76 | 106 | }
|
77 | 107 |
|
78 | 108 | function getImportSpecifiers(namedImport: NamedImport, spaceBraces: boolean): string {
|
|
0 commit comments