@@ -4,6 +4,7 @@ const fs = require('fs');
44const argv = require ( 'yargs-parser' ) ( process . argv . slice ( 2 ) ) ;
55const inquirer = require ( 'inquirer' ) ;
66const chalk = require ( 'chalk' ) ;
7+ const crypto = require ( 'crypto' ) ;
78const { cleanComment } = require ( './cleanComment' ) ;
89
910const grammarsPath = path . resolve ( __dirname , '../src/grammar' ) ;
@@ -13,26 +14,57 @@ const languageEntries = fs.readdirSync(grammarsPath);
1314
1415const baseCmd = 'antlr4ng -Dlanguage=TypeScript -visitor -listener -Xexact-output-dir -o' ;
1516
16- function compile ( language ) {
17- const cmd = ` ${ baseCmd } ${ outputPath } / ${ language } ${ grammarsPath } / ${ language } /*.g4` ;
17+ function getFileHash ( filePath ) {
18+ if ( ! fs . existsSync ( filePath ) ) return null ;
1819
19- if ( language !== 'plsql' && fs . existsSync ( `${ outputPath } /${ language } ` ) ) {
20- console . info ( chalk . green ( `\nRemoving:` , chalk . gray ( `${ outputPath } /${ language } /*` ) ) ) ;
21- fs . rmSync ( `${ outputPath } /${ language } ` , { recursive : true } ) ;
22- }
20+ const fileBuffer = fs . readFileSync ( filePath ) ;
21+ const hashSum = crypto . createHash ( 'sha256' ) ;
22+ hashSum . update ( fileBuffer ) ;
2323
24- console . info ( chalk . green ( 'Executing:' ) , chalk . gray ( cmd ) ) ;
25- exec ( cmd , ( err ) => {
26- if ( err ) {
27- console . error (
28- chalk . redBright ( `\n[Antlr4 compile error]:` ) ,
29- chalk . cyan ( language ) ,
30- chalk . gray ( err )
31- ) ;
32- } else {
33- cleanComment ( language ) ;
34- console . info ( chalk . greenBright ( `Compile ${ language } succeeded!` ) ) ;
24+ return hashSum . digest ( 'hex' ) ;
25+ }
26+
27+ function compile ( language ) {
28+ return new Promise ( ( resolve , reject ) => {
29+ const outputDir = `${ outputPath } /${ language } ` ;
30+ const grammarFiles = fs
31+ . readdirSync ( `${ grammarsPath } /${ language } ` )
32+ . filter ( ( file ) => file . endsWith ( '.g4' ) ) ;
33+ const previousHashes = grammarFiles . map ( ( file ) => ( {
34+ file,
35+ hash : getFileHash ( path . join ( outputDir , file . replace ( '.g4' , '.ts' ) ) ) ,
36+ } ) ) ;
37+
38+ if ( language !== 'plsql' && fs . existsSync ( `${ outputPath } /${ language } ` ) ) {
39+ console . info ( chalk . green ( `\nRemoving:` , chalk . gray ( `${ outputPath } /${ language } /*` ) ) ) ;
40+ fs . rmSync ( `${ outputPath } /${ language } ` , { recursive : true } ) ;
3541 }
42+
43+ const cmd = `${ baseCmd } ${ outputDir } ${ grammarsPath } /${ language } /*.g4` ;
44+ console . info ( chalk . green ( 'Executing:' ) , chalk . gray ( cmd ) ) ;
45+ exec ( cmd , ( err ) => {
46+ if ( err ) {
47+ console . error (
48+ chalk . redBright ( `\n[Antlr4 compile error]:` ) ,
49+ chalk . cyan ( language ) ,
50+ chalk . gray ( err )
51+ ) ;
52+ } else {
53+ cleanComment ( language ) ;
54+ console . info ( chalk . greenBright ( `Compile ${ language } succeeded!` ) ) ;
55+
56+ const changedFiles = grammarFiles . filter ( ( file ) => {
57+ const newHash = getFileHash ( path . join ( outputDir , file . replace ( '.g4' , '.ts' ) ) ) ;
58+ const prevHash = previousHashes . find ( ( h ) => h . file === file ) ?. hash ;
59+ return newHash !== prevHash ;
60+ } ) ;
61+
62+ if ( changedFiles . length > 0 ) {
63+ return reject ( `${ language } not run antlr4` ) ;
64+ }
65+ resolve ( ) ;
66+ }
67+ } ) ;
3668 } ) ;
3769}
3870
@@ -59,22 +91,32 @@ function prompt() {
5991 } ) ;
6092}
6193
94+ async function antlr4AllSql ( ) {
95+ const errors = [ ] ;
96+
97+ const tasks = languageEntries . map ( ( language ) =>
98+ compile ( language ) . catch ( ( err ) => errors . push ( err ) )
99+ ) ;
100+
101+ await Promise . all ( tasks ) ;
102+
103+ if ( errors . length > 0 && argv . check ) {
104+ errors . forEach ( ( error ) => console . error ( chalk . red ( `- ${ error } ` ) ) ) ;
105+ process . exit ( 1 ) ; // 非零退出表示错误
106+ }
107+ }
108+
62109function main ( ) {
63110 if ( argv . all ) {
64- // compile all: yarn antlr4 --all
65- languageEntries . forEach ( ( language ) => {
66- compile ( language ) ;
67- } ) ;
111+ antlr4AllSql ( ) ;
68112 } else if ( argv . lang ) {
69113 // compile single: yarn antlr4 --lang=mysql
70114 const supportedLanguage = languageEntries . find ( ( language ) =>
71115 language . startsWith ( argv . lang )
72116 ) ;
73117
74118 if ( argv . lang === 'all' ) {
75- languageEntries . forEach ( ( language ) => {
76- compile ( language ) ;
77- } ) ;
119+ antlr4AllSql ( ) ;
78120 } else if ( supportedLanguage ) {
79121 compile ( supportedLanguage ) ;
80122 } else {
0 commit comments