1
1
import * as fs from 'fs' ;
2
2
import path = require( 'path' ) ;
3
3
4
- import { Config , FileSystemUtils } from '@src' ;
4
+ import { Config , FileSystemUtils , StringUtils } from '@src' ;
5
5
import { Component } from '@model' ;
6
6
7
7
export class ComponentManager {
8
8
private static componentRegex = / @ C o m p o n e n t \( { / ig;
9
+ private static componentClassNameRegex = / e x p o r t \s + c l a s s \s + ( .* ?) \s + / ims;
9
10
private static templateUrlRegex = / .* t e m p l a t e U r l : .+ \/ ( .+ ) ' / i;
10
11
private static selectorRegex = / .* s e l e c t o r : .+ ' ( .+ ) ' / i;
11
12
private static endBracketRegex = / } \) / i;
12
13
private static routerOutletRegex = / < r o u t e r - o u t l e t .* ?> .* ?< \/ r o u t e r - o u t l e t > / ims;
13
14
15
+ private static routesRegex = / : \s * ?R o u t e s \s * ?= \s * ?\[ ( .* ?) \] / ims;
16
+ private static loadChildrenRegex = / l o a d C h i l d r e n : .* ?t h e n \s * \( .+ ?= > .+ ?\. ( .+ ?) \) / i;
17
+ private static routeComponentRegex = / c o m p o n e n t : \s * ?( \w + ?) \b / ig;
18
+ private static childrenRegex = / c h i l d r e n \s * ?: \s * ?\[ ( .* ?) \] / ims;
19
+
20
+
14
21
public static scanWorkspaceForComponents ( directoryPath : string ) : { [ selector : string ] : Component ; } {
15
- const fsUtils = new FileSystemUtils ( ) ;
16
22
const config = new Config ( ) ;
17
- const componentFilenames = fsUtils . listFiles ( directoryPath , config . excludeDirectories , ComponentManager . isComponentFile ) ;
23
+ const fsUtils = new FileSystemUtils ( ) ;
24
+ const componentOrModuleFilenames = fsUtils . listFiles ( directoryPath , config . excludeDirectories , this . isComponentOrModuleFile ) ;
25
+ const componentFilenames = componentOrModuleFilenames . filter ( FileSystemUtils . isComponentFile ) ;
18
26
const components = ComponentManager . scanComponents ( componentFilenames ) ;
19
27
ComponentManager . enrichComponentsFromComponentTemplates ( components ) ;
28
+ const moduleFilenames = componentOrModuleFilenames . filter ( FileSystemUtils . isModuleFile ) ;
29
+ ComponentManager . enrichComponentsFromModules ( moduleFilenames , components ) ;
20
30
return components ;
21
31
}
22
32
23
- private static isComponentFile ( filename : string ) : boolean {
24
- return filename . endsWith ( '.component.ts' ) ;
33
+ private static isComponentOrModuleFile ( filename : string ) : boolean {
34
+ return FileSystemUtils . isComponentFile ( filename ) || FileSystemUtils . isModuleFile ( filename ) ;
25
35
}
26
36
27
37
private static scanComponents ( componentFilenames : string [ ] ) : { [ selector : string ] : Component ; } {
@@ -55,6 +65,10 @@ export class ComponentManager {
55
65
}
56
66
}
57
67
}
68
+ const componentClassNameMatch = this . componentClassNameRegex . exec ( content ) ;
69
+ if ( componentClassNameMatch !== null ) {
70
+ currentComponent . name = componentClassNameMatch [ 1 ] ;
71
+ }
58
72
compHash [ currentComponent . selector ] = currentComponent ;
59
73
} ) ;
60
74
return compHash ;
@@ -91,4 +105,58 @@ export class ComponentManager {
91
105
const match = this . routerOutletRegex . exec ( template . toString ( ) ) ;
92
106
return match !== null ;
93
107
}
108
+
109
+ private static enrichComponentsFromModules ( moduleFilenames : string [ ] , componentHash : { [ selector : string ] : Component ; } ) {
110
+ moduleFilenames . forEach ( ( moduleFilename ) => {
111
+ const moduleContent = fs . readFileSync ( moduleFilename ) ;
112
+ const match = this . routesRegex . exec ( moduleContent . toString ( ) ) ;
113
+ if ( match !== null ) {
114
+ let routesBody = match [ 1 ] ;
115
+ this . parseRoutesBody ( routesBody , moduleFilename , componentHash ) ;
116
+ }
117
+ } ) ;
118
+ }
119
+
120
+ private static parseRoutesBody ( routesBody : string , moduleFilename : string , componentDict : { [ selector : string ] : Component ; } ) {
121
+ routesBody = StringUtils . removeComments ( routesBody ) ;
122
+ const routesBodyParts = routesBody . split ( "," ) ;
123
+ // We assume that the routing module has a corresponding module with the same name
124
+ // This only works if the routing module is named like 'moduleComponentName'-routing.module.ts
125
+ if ( ! FileSystemUtils . isRoutingModuleFile ( moduleFilename ) ) {
126
+ return ;
127
+ }
128
+ const moduleComponentFilename = moduleFilename . replace ( FileSystemUtils . routingModuleFileExtension , FileSystemUtils . componentFileExtension ) ;
129
+ const componentDictKey = Object . keys ( componentDict ) . find ( key => componentDict [ key ] . filename . endsWith ( moduleComponentFilename ) ) ;
130
+ // if we didn't find the corresponding component we stop because we would not be able to link the components found in the routes to the current module component
131
+ if ( componentDictKey === undefined ) {
132
+ return ;
133
+ }
134
+ const moduleComponent = componentDict [ componentDictKey ] ;
135
+ routesBodyParts . forEach ( ( routesBodyPart ) => {
136
+ const componentMatch = this . routeComponentRegex . exec ( routesBodyPart ) ;
137
+ if ( componentMatch !== null ) {
138
+ const componentName = componentMatch [ 1 ] ;
139
+ const componentSelector = Object . keys ( componentDict ) . find ( key => componentDict [ key ] . name === componentName ) ;
140
+ if ( componentSelector !== undefined ) {
141
+ const component = componentDict [ componentSelector ] ;
142
+ if ( component !== undefined && componentSelector !== moduleComponent . selector ) {
143
+ component . componentsRoutingToThis . push ( moduleComponent ) ;
144
+ }
145
+ }
146
+ }
147
+ else {
148
+ const loadChildrenMatch = this . loadChildrenRegex . exec ( routesBodyPart ) ;
149
+ if ( loadChildrenMatch !== null ) {
150
+ const moduleName = loadChildrenMatch [ 1 ] ;
151
+ console . log ( `${ moduleComponent . name } routing to module ${ moduleName } ` ) ;
152
+ }
153
+ }
154
+ const childrenMatch = this . childrenRegex . exec ( routesBodyPart ) ;
155
+ if ( childrenMatch !== null ) {
156
+ const childrenRoutesBody = childrenMatch [ 1 ] ;
157
+ this . parseRoutesBody ( childrenRoutesBody , moduleFilename , componentDict ) ;
158
+ }
159
+ } ) ;
160
+
161
+ }
94
162
}
0 commit comments