@@ -2,9 +2,11 @@ import wp = require("webpack");
2
2
import fs = require( "fs" ) ;
3
3
import path = require( "path" ) ;
4
4
import util = require( 'util' ) ;
5
+ import readline = require( 'readline' ) ;
5
6
import _ = require( "lodash" ) ;
6
7
import i18next = require( 'i18next' ) ;
7
8
import Backend = require( 'i18next-node-fs-backend' ) ;
9
+ import { ReadableStreamBuffer } from 'stream-buffers' ;
8
10
import { SourceMapConsumer } from 'source-map' ;
9
11
const VirtualModulePlugin = require ( 'virtual-module-webpack-plugin' ) ;
10
12
@@ -26,7 +28,7 @@ async function exists(path: fs.PathLike) {
26
28
}
27
29
}
28
30
29
- function extractArgs ( arg : any , warning ?: ( msg : string ) => void ) {
31
+ function extractArgs ( arg : any , warning ?: ( node : any ) => void ) {
30
32
switch ( arg . type ) {
31
33
case 'Literal' :
32
34
return arg . value ;
@@ -40,7 +42,7 @@ function extractArgs(arg: any, warning?: (msg: string) => void) {
40
42
return res ;
41
43
default :
42
44
if ( warning ) {
43
- warning ( `unable to parse arg ${ arg } ` ) ;
45
+ warning ( arg ) ;
44
46
}
45
47
return null ;
46
48
}
@@ -279,12 +281,45 @@ export default class I18nextPlugin {
279
281
}
280
282
281
283
protected static onTranslateFunctionCall ( this : wp . Parser , plugin : I18nextPlugin , expr : wp . Expression ) {
282
- const args = expr . arguments . map ( ( arg : any ) => extractArgs ( arg , plugin . warningOnCompilation . bind ( plugin ) ) ) ;
283
284
const resource = this . state . current . resource ;
284
285
if ( plugin . sourceMaps [ resource ] === undefined ) {
285
286
plugin . sourceMaps [ resource ] = new SourceMapConsumer ( this . state . current . _source . _sourceMap ) ;
286
287
}
287
288
const sourceMap = plugin . sourceMaps [ resource ] ;
289
+ const args = expr . arguments . map ( ( arg : any ) => extractArgs ( arg , ( arg ) => {
290
+ const beginPos = sourceMap . originalPositionFor ( arg . loc . start ) ;
291
+ const endPos = sourceMap . originalPositionFor ( arg . loc . end ) ;
292
+ if ( beginPos . source !== null ) {
293
+ const originalSource = sourceMap . sourceContentFor ( beginPos . source ) ;
294
+ const sourceLines : string [ ] = [ ] ;
295
+ if ( originalSource !== null ) {
296
+ const buffer = new ReadableStreamBuffer ( ) ;
297
+ buffer . put ( originalSource ) ;
298
+ let lineIdx = 0 ;
299
+ const lineInterface = readline . createInterface ( buffer ) . on ( "line" , ( line : string ) => {
300
+ lineIdx ++ ;
301
+ let beginCol = 0 , endCol = line . length ;
302
+ if ( lineIdx === beginPos . line ) {
303
+ beginCol = beginPos . column as number ;
304
+ }
305
+ if ( lineIdx === endPos . line ) {
306
+ endCol = endPos . column as number ;
307
+ }
308
+ if ( lineIdx >= ( beginPos . line as number ) && lineIdx <= ( endPos . line as number ) ) {
309
+ sourceLines . push ( line . substring ( beginCol , endCol ) ) ;
310
+ }
311
+
312
+ if ( lineIdx === endPos . line ) {
313
+ lineInterface . close ( ) ;
314
+ }
315
+ } ) . on ( "close" , ( ) => {
316
+ plugin . warningOnCompilation ( `unable to parse arg ${ sourceLines . join ( "\n" ) } at ${ resource } :(${ beginPos . line } , ${ beginPos . column } )` ) ;
317
+ } ) ;
318
+ return ;
319
+ }
320
+ }
321
+ plugin . warningOnCompilation ( `unable to parse node at ${ resource } :(${ beginPos . line } , ${ beginPos . column } )` ) ;
322
+ } ) ) ;
288
323
const startPos = sourceMap . originalPositionFor ( expr . loc . start ) ;
289
324
const pos = [ resource , startPos . line , startPos . column ] ;
290
325
0 commit comments