@@ -9,88 +9,58 @@ import { once } from 'events';
9
9
import { EOL } from 'os' ;
10
10
import { promisify } from 'util' ;
11
11
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 ) ) ;
28
18
await withLog ( 'Writing files... ' , writeFiles ( files ) ) ;
29
- await withLog ( 'Updating head.json... ' , updateHead ( ) ) ;
30
19
await withLog ( 'Generating parser...\n' , writeParser ( ) ) ;
31
20
await withLog ( 'Generating contexts... ' , writeParserContexts ( ) ) ;
32
21
await withLog ( 'Compiling typescript files... ' , writeJavascript ( ) ) ;
33
22
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
+ } ;
40
24
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
+ } ;
45
29
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 (
51
32
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
+ ) ;
71
42
72
43
const writeFiles = ( files : { [ file : string ] : string } ) =>
73
44
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
+ ) ;
85
49
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
+ } ;
88
56
89
57
const 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
+ ) ;
91
62
92
- const exportList =
93
- listenerSource
63
+ const exportList = listenerSource
94
64
. split ( EOL )
95
65
. map ( ( l ) => {
96
66
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 () => {
101
71
. reduce ( ( list , context ) => list + ` ${ context } ,${ EOL } ` , '' ) ;
102
72
103
73
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';` ,
106
76
) ;
107
- }
77
+ } ;
108
78
109
79
const 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
+ } ;
113
83
114
- const withLog = async < T > (
84
+ export const withLog = async < T > (
115
85
label : string ,
116
86
promise : Promise < T > ,
117
- fulfilMessage : ( ( value : T ) => string ) = ( ) => 'Done'
87
+ fulfilMessage : ( value : T ) => string = ( ) => 'Done' ,
118
88
) => {
119
89
process . stdout . write ( label ) ;
120
90
try {
121
91
const value = await promise ;
122
- process . stdout . write ( fulfilMessage ( value ) + '\n' )
92
+ process . stdout . write ( fulfilMessage ( value ) + '\n' ) ;
123
93
return value ;
124
94
} catch ( error ) {
125
95
process . stdout . write ( 'Something went wrong\n' ) ;
126
96
throw error ;
127
97
}
128
- }
98
+ } ;
129
99
130
100
const execCommand = async ( command : string ) => {
131
- const childProcess = exec ( command , { cwd : __dirname } )
101
+ const childProcess = exec ( command , { cwd : __dirname } ) ;
132
102
childProcess . stdout . pipe ( process . stdout ) ;
133
103
childProcess . stderr . pipe ( process . stderr ) ;
134
104
135
- const [ code ] = await once ( childProcess , 'exit' ) as [ number ] ;
105
+ const [ code ] = ( await once ( childProcess , 'exit' ) ) as [ number ] ;
136
106
if ( code !== 0 ) throw undefined ;
137
- }
107
+ } ;
138
108
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 ) ;
141
110
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 ;
144
113
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 ;
147
117
148
- main ( ) ;
118
+ if ( require . main === module ) {
119
+ main ( ) ;
120
+ }
0 commit comments