11import { NamedImport } from '../../imports/NamedImport' ;
22import { SymbolSpecifier } from '../../SymbolSpecifier' ;
33import { stringTemplate } from '../../utilities/StringTemplate' ;
4- import { TypescriptGenerationOptions } from '../TypescriptGenerationOptions' ;
4+ import { MultiLineImportRule , TypescriptGenerationOptions } from '../TypescriptGenerationOptions' ;
55import { generateSymbolSpecifier } from './symbolSpecifier' ;
66
7- const importTemplate = stringTemplate `import ${ 0 } from ${ 1 } ` ;
7+ const oneLinerImportTemplate = stringTemplate `import ${ 0 } from ${ 1 } ` ;
88
9- const multiLineImport = stringTemplate `import ${ 3 } {
9+ const multiLineImportTemplate = stringTemplate `import ${ 3 } {
1010${ 0 } ${ 1 }
1111} from ${ 2 } ` ;
1212
13+ const defaultAliasOnlyMultiLineImportTemplate = stringTemplate `import ${ 0 }
14+ from ${ 1 } ` ;
15+
1316/**
1417 * Sort function for symbol specifiers. Does sort after the specifiers name (to lowercase).
1518 *
@@ -23,7 +26,8 @@ function specifierSort(i1: SymbolSpecifier, i2: SymbolSpecifier): number {
2326
2427 if ( strA < strB ) {
2528 return - 1 ;
26- } else if ( strA > strB ) {
29+ }
30+ if ( strA > strB ) {
2731 return 1 ;
2832 }
2933 return 0 ;
@@ -44,34 +48,61 @@ export function generateNamedImport(
4448 stringQuoteStyle,
4549 spaceBraces,
4650 tabSize,
51+ wrapMethod,
4752 multiLineWrapThreshold,
4853 multiLineTrailingComma,
54+ insertSpaces = true ,
4955 } : TypescriptGenerationOptions ,
5056) : string {
51- const space = spaceBraces ? ' ' : '' ;
5257 const lib = `${ stringQuoteStyle } ${ imp . libraryName } ${ stringQuoteStyle } ${ eol } ` ;
53-
54- const specifiers = imp . specifiers . sort ( specifierSort ) . map ( o => generateSymbolSpecifier ( o ) ) . join ( ', ' ) ;
55- let importSpecifiers = `${ space } ${ specifiers } ${ space } ` ;
56- if ( importSpecifiers . trim ( ) . length === 0 ) {
57- 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 ;
5864 }
59-
60- const importString = importTemplate (
61- getImportSpecifiers ( imp , spaceBraces ) ,
62- lib ,
63- ) ;
64-
65- if ( importString . length > multiLineWrapThreshold ) {
66- const spacings = Array ( tabSize + 1 ) . join ( ' ' ) ;
67- return multiLineImport (
68- imp . specifiers . sort ( specifierSort ) . map ( o => `${ spacings } ${ generateSymbolSpecifier ( o ) } ` ) . join ( ',\n' ) ,
69- multiLineTrailingComma ? ',' : '' ,
70- `${ stringQuoteStyle } ${ imp . libraryName } ${ stringQuoteStyle } ${ eol } ` ,
65+ const defaultAliasOnly : boolean = imp . specifiers . length === 0 ;
66+ if ( defaultAliasOnly ) {
67+ return defaultAliasOnlyMultiLineImportTemplate (
7168 imp . defaultAlias ? `${ imp . defaultAlias } , ` : '' ,
69+ `${ stringQuoteStyle } ${ imp . libraryName } ${ stringQuoteStyle } ${ eol } ` ,
7270 ) ;
7371 }
74- 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+ ) ;
75106}
76107
77108function getImportSpecifiers ( namedImport : NamedImport , spaceBraces : boolean ) : string {
0 commit comments