@@ -18,7 +18,11 @@ export default class Resolver {
18
18
PKG_NAME = 'namespaceResolver' ;
19
19
20
20
public constructor ( ) {
21
- this . CWD = vscode . workspace . workspaceFolders ! [ 0 ] . uri . fsPath || '' ;
21
+ try {
22
+ this . CWD = vscode . workspace . workspaceFolders ! [ 0 ] . uri . fsPath ;
23
+ } catch ( error ) {
24
+ this . CWD = '' ;
25
+ }
22
26
23
27
this . getPHPClassList ( ) ;
24
28
}
@@ -27,7 +31,7 @@ export default class Resolver {
27
31
const className = this . resolving ( selection ) ;
28
32
29
33
if ( className === undefined ) {
30
- return this . showErrorMessage ( 'No class is selected.' ) ;
34
+ return this . showMessage ( 'No class is selected.' , true ) ;
31
35
}
32
36
33
37
let fqcn ;
@@ -159,7 +163,7 @@ export default class Resolver {
159
163
}
160
164
161
165
if ( this . hasAliasConflict ( useStatements , classBaseName ) ) {
162
- return this . showErrorMessage ( `class : '${ classBaseName } ' is used as alias.` ) ;
166
+ return this . showMessage ( `class : '${ classBaseName } ' is used as alias.` , true ) ;
163
167
}
164
168
165
169
if ( replaceClassAfterImport ) {
@@ -168,7 +172,7 @@ export default class Resolver {
168
172
169
173
return this . insert ( fqcn , declarationLines ) ;
170
174
} catch ( error ) {
171
- return this . showErrorMessage ( error . message ) ;
175
+ return this . showMessage ( error . message , true ) ;
172
176
}
173
177
}
174
178
@@ -209,7 +213,7 @@ export default class Resolver {
209
213
}
210
214
211
215
if ( this . hasAliasConflict ( useStatements , alias ) ) {
212
- await this . showErrorMessage ( `alias : '${ alias } ' is already in use.` ) ;
216
+ await this . showMessage ( `alias : '${ alias } ' is already in use.` , true ) ;
213
217
214
218
return this . insertAsAlias ( selection , fqcn , useStatements , declarationLines ) ;
215
219
}
@@ -219,22 +223,38 @@ export default class Resolver {
219
223
220
224
async insertNewUseStatement ( selection , fqcn , useStatements , declarationLines ) {
221
225
if ( useStatements . find ( ( use ) => use . text == fqcn ) ) {
222
- await this . showErrorMessage ( `'${ fqcn } ' already exists` ) ;
226
+ return this . showMessage ( `'${ fqcn } ' already exists` , true ) ;
223
227
}
224
228
225
229
const editor = this . EDITOR ;
226
- const className = fqcn . replace ( / \w + \\ / g , '' ) ;
227
- const similarImport = useStatements . find ( ( use ) => use . text . endsWith ( className ) || fqcn . startsWith ( use . text ) ) ;
230
+ const classBaseName = fqcn . match ( / ( \w + ) / g ) . pop ( ) ;
231
+ const similarImport = useStatements . find ( ( use ) => use . text . endsWith ( classBaseName ) || fqcn . startsWith ( use . text ) ) ;
228
232
229
233
if ( similarImport ) {
230
- this . showErrorMessage ( `use statement '${ similarImport . text } ' already exists` ) ;
234
+ if ( this . config ( 'forceReplaceSimilarImports' ) ) {
235
+ let useCall = `use ${ fqcn } ` ;
236
+
237
+ if ( similarImport . alias ) {
238
+ useCall = `${ useCall } as ${ similarImport . alias } ` ;
239
+ }
240
+
241
+ return editor . edit ( ( textEdit ) => {
242
+ textEdit . replace (
243
+ // @ts -ignore
244
+ editor . document . lineAt ( similarImport . line ) . range ,
245
+ `${ useCall } ;` ,
246
+ ) ;
247
+ } , { undoStopBefore : false , undoStopAfter : false } ) ;
248
+ } else {
249
+ return this . showMessage ( `use statement '${ similarImport . text } ' already exists` , true ) ;
250
+ }
231
251
}
232
252
233
253
await editor . edit ( ( textEdit ) => {
234
254
textEdit . replace (
235
255
// @ts -ignore
236
256
editor . document . getWordRangeAtPosition ( selection . active , regexWordWithNamespace ) ,
237
- className ,
257
+ classBaseName ,
238
258
) ;
239
259
} , { undoStopBefore : false , undoStopAfter : false } ) ;
240
260
@@ -252,7 +272,7 @@ export default class Resolver {
252
272
let className = resolving ;
253
273
254
274
if ( resolving === null ) {
255
- return this . showErrorMessage ( 'No class is selected.' ) ;
275
+ return this . showMessage ( 'No class is selected.' , true ) ;
256
276
}
257
277
258
278
if ( / \w + \\ / . test ( resolving ) ) {
@@ -301,7 +321,7 @@ export default class Resolver {
301
321
302
322
await this . showMessage ( '$(check) Imports are sorted.' ) ;
303
323
} catch ( error ) {
304
- return this . showErrorMessage ( error . message ) ;
324
+ return this . showMessage ( error . message , true ) ;
305
325
}
306
326
}
307
327
@@ -319,7 +339,7 @@ export default class Resolver {
319
339
) ;
320
340
321
341
if ( parsedNamespaces . length === 0 ) {
322
- return this . showErrorMessage ( '$(circle-slash) The class is not found.' ) ;
342
+ return this . showMessage ( '$(circle-slash) The class is not found.' , true ) ;
323
343
}
324
344
325
345
return parsedNamespaces ;
@@ -551,7 +571,7 @@ export default class Resolver {
551
571
return document . getText ( wordRange ) ;
552
572
}
553
573
554
- async showMessage ( message , error = false ) {
574
+ async showMessage ( message , error = false ) : Promise < string | vscode . Disposable | undefined > {
555
575
if ( this . config ( 'showMessageOnStatusBar' ) ) {
556
576
return vscode . window . setStatusBarMessage ( message , 3000 ) ;
557
577
}
@@ -563,10 +583,6 @@ export default class Resolver {
563
583
: vscode . window . showInformationMessage ( `PHP Namespace Resolver: ${ message } ` ) ;
564
584
}
565
585
566
- showErrorMessage ( message ) {
567
- return this . showMessage ( message , true ) ;
568
- }
569
-
570
586
/**
571
587
* @param uri: ?vscode.Uri
572
588
*/
@@ -585,12 +601,19 @@ export default class Resolver {
585
601
try {
586
602
composerFile = await this . findComposerFileByUri ( currentUri , returnDontInsert ) ;
587
603
psr4 = await this . getComposerFileData ( composerFile , returnDontInsert ) ;
588
- ns = await this . createNamespace ( currentUri , psr4 , returnDontInsert ) ;
604
+ ns = await this . createNamespace (
605
+ currentUri ,
606
+ {
607
+ psrData : psr4 ,
608
+ composerFilePath : composerFile ,
609
+ } ,
610
+ returnDontInsert ,
611
+ ) ;
589
612
} catch ( error ) {
590
613
return undefined ;
591
614
}
592
615
593
- const namespace = '\n' + 'namespace ' + ns + ';' + '\n\n ' ;
616
+ const namespace = '\n' + 'namespace ' + ns + ';' + '\n' ;
594
617
595
618
if ( returnDontInsert ) {
596
619
return namespace ;
@@ -619,7 +642,7 @@ export default class Resolver {
619
642
) ;
620
643
}
621
644
} catch ( error ) {
622
- await this . showErrorMessage ( error . message ) ;
645
+ await this . showMessage ( error . message , true ) ;
623
646
624
647
return undefined ;
625
648
}
@@ -630,7 +653,7 @@ export default class Resolver {
630
653
631
654
if ( ! composerFile ) {
632
655
if ( ! ignoreError ) {
633
- await this . showErrorMessage ( 'No composer.json file found' ) ;
656
+ await this . showMessage ( 'No composer.json file found' , true ) ;
634
657
}
635
658
636
659
throw new Error ( ) ;
@@ -647,7 +670,7 @@ export default class Resolver {
647
670
psr4 = composerJson [ 'autoload' ] [ 'psr-4' ] ;
648
671
} catch ( error ) {
649
672
if ( ! ignoreError ) {
650
- await this . showErrorMessage ( 'No psr-4 key in composer.json autoload object' ) ;
673
+ await this . showMessage ( 'No psr-4 key in composer.json autoload object' , true ) ;
651
674
}
652
675
653
676
throw new Error ( ) ;
@@ -664,12 +687,13 @@ export default class Resolver {
664
687
return psr4 ;
665
688
}
666
689
667
- async createNamespace ( currentUri : vscode . Uri , psr4 , ignoreError = true ) : Promise < any > {
690
+ async createNamespace ( currentUri : vscode . Uri , composer : { psrData ?: any ; composerFilePath : string ; } , ignoreError = true ) : Promise < any > {
668
691
const currentFilePath = currentUri ?. path ;
669
- const workspaceFolder = vscode . workspace . getWorkspaceFolder ( currentUri ) ?. uri . fsPath ;
692
+ const composerFileDir = this . getFileDirFromPath ( composer . composerFilePath ) ;
670
693
const currentFileDir = this . getFileDirFromPath ( currentFilePath ) ;
694
+ const psr4 = composer . psrData ;
671
695
672
- let currentRelativePath : any = currentFileDir . replace ( `${ workspaceFolder } /` , '' ) ;
696
+ let currentRelativePath : any = currentFileDir . replace ( `${ composerFileDir } /` , '' ) ;
673
697
674
698
// this is a way to always match with psr-4 entries
675
699
if ( ! currentRelativePath . endsWith ( '/' ) ) {
@@ -680,7 +704,7 @@ export default class Resolver {
680
704
681
705
if ( ! namespaceBase ) {
682
706
if ( ! ignoreError ) {
683
- await this . showErrorMessage ( 'path parent directory not found under composer.json autoload object' ) ;
707
+ await this . showMessage ( 'path parent directory is not found under composer.json autoload object' , true ) ;
684
708
}
685
709
686
710
throw new Error ( ) ;
@@ -701,16 +725,16 @@ export default class Resolver {
701
725
702
726
if ( ! namespaceBase ) {
703
727
if ( ! ignoreError ) {
704
- await this . showErrorMessage ( 'no namespace found for current file parent directory' ) ;
728
+ await this . showMessage ( 'no namespace found for current file parent directory' , true ) ;
705
729
}
706
730
707
731
throw new Error ( ) ;
708
732
}
709
733
710
734
let ns : any = null ;
711
- const lower = namespaceBase . toLowerCase ( ) ;
735
+ const namespaceBaseLower = namespaceBase . toLowerCase ( ) ;
712
736
713
- if ( ! currentRelativePath || currentRelativePath == lower ) { // dir already namespaced
737
+ if ( ! currentRelativePath || currentRelativePath == namespaceBaseLower ) { // dir already namespaced
714
738
ns = namespaceBase ;
715
739
} else { // add parent dir/s to base namespace
716
740
ns = `${ namespaceBase } \\${ currentRelativePath } ` ;
0 commit comments