@@ -9,88 +9,58 @@ import { once } from 'events';
99import { EOL } from 'os' ;
1010import { promisify } from 'util' ;
1111
12- const grammerFiles = [
13- 'JavaParser.g4' ,
14- 'JavaLexer.g4'
15- ] ;
16-
17- const main = async ( ) => {
18- const isStale = await withLog (
19- 'Checking if head is stale... ' ,
20- getIsStale ( ) ,
21- isStaleValue => isStaleValue ? 'Stale' : 'Up-to date'
22- )
23- if ( ! isStale && ! process . argv . includes ( '--force' ) ) {
24- console . log ( 'Exiting, use --force to build anyway' ) ;
25- return ;
26- }
27- const files = await withLog ( 'Fetching files from upstream... ' , getFiles ( ) ) ;
12+ export const grammerFiles = [ 'JavaParser.g4' , 'JavaLexer.g4' ] ;
13+ export const grammerRoot = 'src/parser' ;
14+
15+ export const main = async ( ) => {
16+ const heads = await withLog ( 'Reading head.json ' , getHead ( ) ) ;
17+ const files = await withLog ( 'Fetching files from upstream... ' , getFiles ( heads ) ) ;
2818 await withLog ( 'Writing files... ' , writeFiles ( files ) ) ;
29- await withLog ( 'Updating head.json... ' , updateHead ( ) ) ;
3019 await withLog ( 'Generating parser...\n' , writeParser ( ) ) ;
3120 await withLog ( 'Generating contexts... ' , writeParserContexts ( ) ) ;
3221 await withLog ( 'Compiling typescript files... ' , writeJavascript ( ) ) ;
3322 console . log ( 'Build successful!' ) ;
34- }
35-
36- const getIsStale = async ( ) => {
37- const [ head , upstreamHead ] = await Promise . all ( [ getHead ( ) , getUpstreamHead ( ) ] ) ;
38- return grammerFiles . some ( file => head [ file ] !== upstreamHead [ file ] ) ;
39- }
23+ } ;
4024
41- const getHead = async ( ) =>
42- JSON . parse (
43- await fs . readFile ( path . join ( __dirname , 'src/head.json' ) , 'utf-8' )
44- ) as { [ file : string ] : string } ;
25+ export const getHead = async ( ) =>
26+ JSON . parse ( await fs . readFile ( path . join ( __dirname , 'src/head.json' ) , 'utf-8' ) ) as {
27+ [ file : string ] : string ;
28+ } ;
4529
46- let upstreamHeadCache : { [ file : string ] : string } | undefined ;
47- const getUpstreamHead = async ( ) => {
48- if ( upstreamHeadCache ) return upstreamHeadCache ;
49-
50- const upstreamHead = mergeAll (
30+ const getFiles = async ( heads : { [ key : string ] : string } ) =>
31+ mergeAll (
5132 await Promise . all (
52- grammerFiles . map ( async file => {
53- const res = await fetch ( `https://api.github.com/repos/antlr/grammars-v4/commits?path=java/java/${ file } ` ) ;
54- const commits = await res . json ( ) ;
55- return { [ file ] : commits [ 0 ] . sha as string } ;
56- } )
57- )
58- )
59- upstreamHeadCache = upstreamHead ;
60- return upstreamHead ;
61- }
62-
63- const getFiles = async ( ) =>
64- mergeAll ( await Promise . all (
65- grammerFiles . map ( async file => {
66- const res = await fetch ( `https://raw.githubusercontent.com/antlr/grammars-v4/master/java/java/${ file } ` )
67- const data = await res . text ( ) ;
68- return { [ file ] : data } ;
69- } )
70- ) )
33+ grammerFiles . map ( async ( file ) => {
34+ const res = await fetch (
35+ `https://raw.githubusercontent.com/antlr/grammars-v4/${ heads [ file ] } /java/java/${ file } ` ,
36+ ) ;
37+ const data = await res . text ( ) ;
38+ return { [ file ] : data } ;
39+ } ) ,
40+ ) ,
41+ ) ;
7142
7243const writeFiles = ( files : { [ file : string ] : string } ) =>
7344 Promise . all (
74- Object . entries ( files )
75- . map ( ( [ file , data ] ) =>
76- fs . writeFile ( path . join ( __dirname , 'src/parser/' , file ) , data )
77- )
78- )
79-
80- const updateHead = async ( ) =>
81- fs . writeFile (
82- path . join ( __dirname , 'src/head.json' ) ,
83- JSON . stringify ( await getUpstreamHead ( ) , null , ' ' )
84- )
45+ Object . entries ( files ) . map ( ( [ file , data ] ) =>
46+ fs . writeFile ( path . join ( __dirname , grammerRoot , file ) , data ) ,
47+ ) ,
48+ ) ;
8549
86- const writeParser = ( ) =>
87- execCommand ( `${ prependBinDir ( 'antlr4ts' ) } -visitor -o src/parser -Xexact-output-dir src/parser/JavaLexer.g4 src/parser/JavaParser.g4` )
50+ const writeParser = ( ) => {
51+ const binary = prependBinDir ( 'antlr4ts' ) ;
52+ return execCommand (
53+ `${ binary } -visitor -o ${ grammerRoot } -Xexact-output-dir ${ grammerRoot } /JavaLexer.g4 ${ grammerRoot } /JavaParser.g4` ,
54+ ) ;
55+ } ;
8856
8957const writeParserContexts = async ( ) => {
90- const listenerSource = await fs . readFile ( path . join ( __dirname , '/src/parser/JavaParserListener.ts' ) , 'utf-8' ) ;
58+ const listenerSource = await fs . readFile (
59+ path . join ( __dirname , grammerRoot , 'JavaParserListener.ts' ) ,
60+ 'utf-8' ,
61+ ) ;
9162
92- const exportList =
93- listenerSource
63+ const exportList = listenerSource
9464 . split ( EOL )
9565 . map ( ( l ) => {
9666 const matches = l . match ( / i m p o r t \s * \{ \s * ( .* C o n t e x t ) \s * \} .* / ) ;
@@ -101,48 +71,50 @@ const writeParserContexts = async () => {
10171 . reduce ( ( list , context ) => list + ` ${ context } ,${ EOL } ` , '' ) ;
10272
10373 await fs . writeFile (
104- path . join ( __dirname , '/src/parser/ JavaContexts.ts') ,
105- `export {${ EOL } ${ exportList } } from './JavaParser';`
74+ path . join ( __dirname , grammerRoot , ' JavaContexts.ts') ,
75+ `export {${ EOL } ${ exportList } } from './JavaParser';` ,
10676 ) ;
107- }
77+ } ;
10878
10979const writeJavascript = async ( ) => {
110- await promisify ( rimraf ) ( path . join ( __dirname , '/dist' ) )
111- await execCommand ( prependBinDir ( 'tsc' ) )
112- }
80+ await promisify ( rimraf ) ( path . join ( __dirname , '/dist' ) ) ;
81+ await execCommand ( prependBinDir ( 'tsc' ) ) ;
82+ } ;
11383
114- const withLog = async < T > (
84+ export const withLog = async < T > (
11585 label : string ,
11686 promise : Promise < T > ,
117- fulfilMessage : ( ( value : T ) => string ) = ( ) => 'Done'
87+ fulfilMessage : ( value : T ) => string = ( ) => 'Done' ,
11888) => {
11989 process . stdout . write ( label ) ;
12090 try {
12191 const value = await promise ;
122- process . stdout . write ( fulfilMessage ( value ) + '\n' )
92+ process . stdout . write ( fulfilMessage ( value ) + '\n' ) ;
12393 return value ;
12494 } catch ( error ) {
12595 process . stdout . write ( 'Something went wrong\n' ) ;
12696 throw error ;
12797 }
128- }
98+ } ;
12999
130100const execCommand = async ( command : string ) => {
131- const childProcess = exec ( command , { cwd : __dirname } )
101+ const childProcess = exec ( command , { cwd : __dirname } ) ;
132102 childProcess . stdout . pipe ( process . stdout ) ;
133103 childProcess . stderr . pipe ( process . stderr ) ;
134104
135- const [ code ] = await once ( childProcess , 'exit' ) as [ number ] ;
105+ const [ code ] = ( await once ( childProcess , 'exit' ) ) as [ number ] ;
136106 if ( code !== 0 ) throw undefined ;
137- }
107+ } ;
138108
139- const prependBinDir = ( p : string ) =>
140- path . join ( __dirname , '/node_modules/.bin/' , p ) ;
109+ const prependBinDir = ( p : string ) => path . join ( __dirname , '/node_modules/.bin/' , p ) ;
141110
142- type MergeAll = < T extends object [ ] > ( xs : T ) => UnionToIntersection < T [ number ] > ;
143- const mergeAll : MergeAll = xs => xs . reduce ( ( m , x ) => ( { ...m , ...x } ) , { } ) as any ;
111+ export type MergeAll = < T extends object [ ] > ( xs : T ) => UnionToIntersection < T [ number ] > ;
112+ export const mergeAll : MergeAll = ( xs ) => xs . reduce ( ( m , x ) => ( { ...m , ...x } ) , { } ) as any ;
144113
145- type UnionToIntersection < U > =
146- ( U extends any ? ( k : U ) => void : never ) extends ( ( k : infer I ) => void ) ? I : never
114+ type UnionToIntersection < U > = ( U extends any ? ( k : U ) => void : never ) extends ( k : infer I ) => void
115+ ? I
116+ : never ;
147117
148- main ( ) ;
118+ if ( require . main === module ) {
119+ main ( ) ;
120+ }
0 commit comments