11import { RelativePattern , Uri } from 'vscode' ;
22import { Indexer } from 'indexer/Indexer' ;
33import FileSystem from 'util/FileSystem' ;
4- import { AutoloadNamespaceData } from './types' ;
4+ import { Namespace } from './types' ;
55
6- export default class AutoloadNamespaceIndexer extends Indexer < AutoloadNamespaceData > {
6+ export default class AutoloadNamespaceIndexer extends Indexer < Namespace [ ] > {
77 public static readonly KEY = 'autoloadNamespace' ;
88
99 public getId ( ) : string {
@@ -18,7 +18,7 @@ export default class AutoloadNamespaceIndexer extends Indexer<AutoloadNamespaceD
1818 return new RelativePattern ( uri , '**/composer.json' ) ;
1919 }
2020
21- public async indexFile ( uri : Uri ) : Promise < AutoloadNamespaceData | undefined > {
21+ public async indexFile ( uri : Uri ) : Promise < Namespace [ ] | undefined > {
2222 const content = await FileSystem . readFile ( uri ) ;
2323 const composer = JSON . parse ( content ) ;
2424
@@ -27,34 +27,75 @@ export default class AutoloadNamespaceIndexer extends Indexer<AutoloadNamespaceD
2727 }
2828
2929 const baseDir = Uri . joinPath ( uri , '..' ) ;
30- const data : AutoloadNamespaceData = { } ;
30+ const data : Namespace [ ] = [ ] ;
3131
3232 // Handle PSR-4 autoloading
3333 if ( composer . autoload [ 'psr-4' ] ) {
34- for ( const [ namespace , paths ] of Object . entries ( composer . autoload [ 'psr-4' ] ) ) {
35- const directories = Array . isArray ( paths ) ? paths : [ paths ] ;
34+ const namespaces = await this . indexNamespaces ( composer . autoload [ 'psr-4' ] , baseDir ) ;
3635
37- data [ this . normalizeNamespace ( namespace ) ] = directories . map (
38- ( dir : string ) => Uri . joinPath ( baseDir , dir . replace ( / ^ \. \/ / , '' ) ) . fsPath
39- ) ;
40- }
36+ data . push ( ...namespaces ) ;
4137 }
4238
43- // Handle PSR-0 autoloading
39+ // // Handle PSR-0 autoloading
4440 if ( composer . autoload [ 'psr-0' ] ) {
45- for ( const [ namespace , paths ] of Object . entries ( composer . autoload [ 'psr-0' ] ) ) {
46- const directories = Array . isArray ( paths ) ? paths : [ paths ] ;
41+ const namespaces = await this . indexNamespaces ( composer . autoload [ 'psr-0' ] , baseDir ) ;
4742
48- data [ this . normalizeNamespace ( namespace ) ] = directories . map (
49- ( dir : string ) => Uri . joinPath ( baseDir , dir . replace ( / ^ \. \/ / , '' ) ) . fsPath
50- ) ;
51- }
43+ data . push ( ...namespaces ) ;
5244 }
5345
5446 return data ;
5547 }
5648
49+ private async indexNamespaces (
50+ autoLoadData : Record < string , string [ ] > ,
51+ baseDir : Uri
52+ ) : Promise < Namespace [ ] > {
53+ const promises : Promise < Namespace [ ] > [ ] = [ ] ;
54+
55+ for ( const [ namespace , paths ] of Object . entries ( autoLoadData ) ) {
56+ const directories = Array . isArray ( paths ) ? paths : [ paths ] ;
57+
58+ for ( const directory of directories ) {
59+ promises . push ( this . expandNamespaces ( namespace , baseDir , directory ) ) ;
60+ }
61+ }
62+
63+ const namespaces = await Promise . all ( promises ) ;
64+ return namespaces . flat ( ) ;
65+ }
66+
67+ private async expandNamespaces (
68+ baseNamespace : string ,
69+ baseDirectory : Uri ,
70+ relativeBaseDirectory : string
71+ ) : Promise < Namespace [ ] > {
72+ const baseDirectoryUri = Uri . joinPath ( baseDirectory , relativeBaseDirectory . replace ( / \\ $ / , '' ) ) ;
73+ const files = await FileSystem . readDirectoryRecursive ( baseDirectoryUri ) ;
74+
75+ return files
76+ . filter ( file => file . endsWith ( '.php' ) )
77+ . filter ( file => {
78+ const parts = file . split ( '/' ) ;
79+ const filename = parts [ parts . length - 1 ] ;
80+ return filename . charAt ( 0 ) === filename . charAt ( 0 ) . toUpperCase ( ) ;
81+ } )
82+ . map ( file => {
83+ const namespace = file . replace ( '.php' , '' ) ;
84+
85+ const fqn = this . normalizeNamespace (
86+ `${ this . normalizeNamespace ( baseNamespace ) } \\${ namespace . replace ( / \/ / g, '\\' ) } `
87+ ) ;
88+
89+ return {
90+ fqn,
91+ prefix : baseNamespace ,
92+ baseDirectory : baseDirectoryUri . fsPath ,
93+ path : Uri . joinPath ( baseDirectoryUri , file ) . fsPath ,
94+ } ;
95+ } ) ;
96+ }
97+
5798 private normalizeNamespace ( namespace : string ) : string {
58- return namespace . replace ( / \\ $ / , '' ) ;
99+ return namespace . replace ( / \\ $ / , '' ) . replace ( / ^ \\ / , '' ) ;
59100 }
60101}
0 commit comments