@@ -20,9 +20,18 @@ import './handlebars/method-generate-helper';
20
20
21
21
import { IGenOptions } from '../types' ;
22
22
23
+ function formatImport ( item : string ) {
24
+ const prefix = / ^ \. / . test ( item ) ? '' : './' ;
25
+ const arr = item . split ( '/' ) ;
26
+ const filename = arr [ arr . length - 1 ] ;
27
+ return prefix + filename . replace ( '.proto' , '' ) ;
28
+ }
29
+
23
30
/** Set Compiler */
24
31
export class Compiler {
25
32
constructor ( private readonly options : IGenOptions ) { }
33
+ private protoFiles : string [ ] = [ ] ;
34
+ private protoInfo = { } ;
26
35
27
36
private resolveRootPath ( root : Root ) : void {
28
37
const paths = this . options . path ;
@@ -105,7 +114,7 @@ export class Compiler {
105
114
}
106
115
}
107
116
108
- private output ( file : string , pkg : string , tmpl : string ) : void {
117
+ private output ( file : string , tmpl : string ) : void {
109
118
const root = new Root ( ) ;
110
119
111
120
this . resolveRootPath ( root ) ;
@@ -119,7 +128,37 @@ export class Compiler {
119
128
120
129
this . walkTree ( root ) ;
121
130
122
- const results = compile ( tmpl ) ( root ) ;
131
+ let results = compile ( tmpl ) ( root ) ;
132
+ const packageArr = [ ] ;
133
+
134
+ // 处理继承问题
135
+ results = results . replace ( "'@midwayjs/grpc';" , matched => {
136
+ return [ matched ]
137
+ . concat (
138
+ this . protoInfo [ file ] . imports . map ( item => {
139
+ packageArr . push ( this . findPackage ( item ) ) ;
140
+ return `import { ${ this . findPackage ( item ) } } from '${ formatImport (
141
+ item
142
+ ) } ';`;
143
+ } )
144
+ )
145
+ . join ( '\n' ) ;
146
+ } ) ;
147
+
148
+ // 移除继承的代码
149
+ for ( const name of packageArr ) {
150
+ const regexp = new RegExp (
151
+ `\\/\\*.+package ${ name } start[\\s\\S]*${ name } end \\*\\/` ,
152
+ 'gm'
153
+ ) ;
154
+ results = results . replace ( regexp , '' ) ;
155
+ }
156
+
157
+ // 清理空导入
158
+ results = results . replace ( / i m p o r t { { 2 } } f r o m ' .+ ' ; \n / , '' ) ;
159
+
160
+ // 清理最后的换行
161
+ results = results . replace ( / \n + $ / , '\n' ) ;
123
162
124
163
const outputFile = this . options . output
125
164
? join ( this . options . output , basename ( file ) )
@@ -132,22 +171,6 @@ export class Compiler {
132
171
outputFileSync ( outputPath , results , 'utf8' ) ;
133
172
}
134
173
135
- private generate ( path : string , pkg : string ) : void {
136
- const hbTemplate = resolve ( __dirname , '../../template.hbs' ) ;
137
-
138
- if ( ! existsSync ( hbTemplate ) ) {
139
- throw new Error ( `Template ${ hbTemplate } is not found` ) ;
140
- }
141
-
142
- const tmpl = readFileSync ( hbTemplate , 'utf8' ) ;
143
-
144
- if ( this . options . verbose ) {
145
- console . log ( chalk . blueBright ( '-- found: ' ) + chalk . gray ( path ) ) ;
146
- }
147
-
148
- this . output ( path , pkg , tmpl ) ;
149
- }
150
-
151
174
private getProtoFiles ( pkg : string ) : void {
152
175
if ( ! existsSync ( pkg ) ) {
153
176
throw new Error ( `Directory ${ pkg } is not exist` ) ;
@@ -166,7 +189,10 @@ export class Compiler {
166
189
if ( stat . isDirectory ( ) ) {
167
190
this . getProtoFiles ( filename ) ;
168
191
} else if ( filename . indexOf ( this . options . target . join ( ) ) > - 1 ) {
169
- this . generate ( filename , pkg ) ;
192
+ if ( this . options . verbose ) {
193
+ console . log ( chalk . blueBright ( '-- found: ' ) + chalk . gray ( filename ) ) ;
194
+ }
195
+ this . protoFiles . push ( filename ) ;
170
196
}
171
197
}
172
198
}
@@ -177,5 +203,43 @@ export class Compiler {
177
203
this . getProtoFiles ( pkg ) ;
178
204
}
179
205
} ) ;
206
+
207
+ // 提前分析 package 和导入的情况
208
+ for ( const filename of this . protoFiles ) {
209
+ this . protoInfo [ filename ] = { } ;
210
+ const originFile = readFileSync ( filename , 'utf8' ) ;
211
+ const regex1 = / i m p o r t \s " ( .+ ) " ; / g;
212
+ let array1 ;
213
+ const result = [ ] ;
214
+ while ( ( array1 = regex1 . exec ( originFile ) ) !== null ) {
215
+ result . push ( array1 [ 1 ] ) ;
216
+ }
217
+ const packageRegexp = / p a c k a g e \s + ( .+ ) ; / ;
218
+ const arr = packageRegexp . exec ( originFile ) ;
219
+ this . protoInfo [ filename ] = {
220
+ packageName : arr [ 1 ] ,
221
+ imports : result ,
222
+ } ;
223
+ }
224
+
225
+ const hbTemplate = resolve ( __dirname , '../../template.hbs' ) ;
226
+ if ( ! existsSync ( hbTemplate ) ) {
227
+ throw new Error ( `Template ${ hbTemplate } is not found` ) ;
228
+ }
229
+ const tmpl = readFileSync ( hbTemplate , 'utf8' ) ;
230
+
231
+ for ( const filename of this . protoFiles ) {
232
+ this . output ( filename , tmpl ) ;
233
+ }
234
+ }
235
+
236
+ findPackage ( p : string ) : string {
237
+ p = p . replace ( / \. + \/ / g, '' ) ;
238
+ for ( const key of Object . keys ( this . protoInfo ) ) {
239
+ if ( key . lastIndexOf ( p ) !== - 1 ) {
240
+ return this . protoInfo [ key ] . packageName ;
241
+ }
242
+ }
243
+ return '' ;
180
244
}
181
245
}
0 commit comments