@@ -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' ) ;
@@ -15,26 +16,57 @@ const languageEntries = fs.readdirSync(grammarsPath).filter((language) => {
1516
1617const baseCmd = 'antlr4ng -Dlanguage=TypeScript -visitor -listener -Xexact-output-dir -o' ;
1718
18- function compile ( language ) {
19- const cmd = ` ${ baseCmd } ${ outputPath } / ${ language } ${ grammarsPath } / ${ language } /*.g4` ;
19+ function getFileHash ( filePath ) {
20+ if ( ! fs . existsSync ( filePath ) ) return null ;
2021
21- if ( language !== 'plsql' && fs . existsSync ( `${ outputPath } /${ language } ` ) ) {
22- console . info ( chalk . green ( `\nRemoving:` , chalk . gray ( `${ outputPath } /${ language } /*` ) ) ) ;
23- fs . rmSync ( `${ outputPath } /${ language } ` , { recursive : true } ) ;
24- }
22+ const fileBuffer = fs . readFileSync ( filePath ) ;
23+ const hashSum = crypto . createHash ( 'sha256' ) ;
24+ hashSum . update ( fileBuffer ) ;
2525
26- console . info ( chalk . green ( 'Executing:' ) , chalk . gray ( cmd ) ) ;
27- exec ( cmd , ( err ) => {
28- if ( err ) {
29- console . error (
30- chalk . redBright ( `\n[Antlr4 compile error]:` ) ,
31- chalk . cyan ( language ) ,
32- chalk . gray ( err )
33- ) ;
34- } else {
35- cleanComment ( language ) ;
36- console . info ( chalk . greenBright ( `Compile ${ language } succeeded!` ) ) ;
26+ return hashSum . digest ( 'hex' ) ;
27+ }
28+
29+ function compile ( language ) {
30+ return new Promise ( ( resolve , reject ) => {
31+ const outputDir = `${ outputPath } /${ language } ` ;
32+ const grammarFiles = fs
33+ . readdirSync ( `${ grammarsPath } /${ language } ` )
34+ . filter ( ( file ) => file . endsWith ( '.g4' ) ) ;
35+ const previousHashes = grammarFiles . map ( ( file ) => ( {
36+ file,
37+ hash : getFileHash ( path . join ( outputDir , file . replace ( '.g4' , '.ts' ) ) ) ,
38+ } ) ) ;
39+
40+ if ( language !== 'plsql' && fs . existsSync ( `${ outputPath } /${ language } ` ) ) {
41+ console . info ( chalk . green ( `\nRemoving:` , chalk . gray ( `${ outputPath } /${ language } /*` ) ) ) ;
42+ fs . rmSync ( `${ outputPath } /${ language } ` , { recursive : true } ) ;
3743 }
44+
45+ const cmd = `${ baseCmd } ${ outputDir } ${ grammarsPath } /${ language } /*.g4` ;
46+ console . info ( chalk . green ( 'Executing:' ) , chalk . gray ( cmd ) ) ;
47+ exec ( cmd , ( err ) => {
48+ if ( err ) {
49+ console . error (
50+ chalk . redBright ( `\n[Antlr4 compile error]:` ) ,
51+ chalk . cyan ( language ) ,
52+ chalk . gray ( err )
53+ ) ;
54+ } else {
55+ cleanComment ( language ) ;
56+ console . info ( chalk . greenBright ( `Compile ${ language } succeeded!` ) ) ;
57+
58+ const changedFiles = grammarFiles . filter ( ( file ) => {
59+ const newHash = getFileHash ( path . join ( outputDir , file . replace ( '.g4' , '.ts' ) ) ) ;
60+ const prevHash = previousHashes . find ( ( h ) => h . file === file ) ?. hash ;
61+ return newHash !== prevHash ;
62+ } ) ;
63+
64+ if ( changedFiles . length > 0 ) {
65+ return reject ( `${ language } not run antlr4` ) ;
66+ }
67+ resolve ( ) ;
68+ }
69+ } ) ;
3870 } ) ;
3971}
4072
@@ -61,22 +93,32 @@ function prompt() {
6193 } ) ;
6294}
6395
96+ async function antlr4AllSql ( ) {
97+ const errors = [ ] ;
98+
99+ const tasks = languageEntries . map ( ( language ) =>
100+ compile ( language ) . catch ( ( err ) => errors . push ( err ) )
101+ ) ;
102+
103+ await Promise . all ( tasks ) ;
104+
105+ if ( errors . length > 0 && argv . check ) {
106+ errors . forEach ( ( error ) => console . error ( chalk . red ( `- ${ error } ` ) ) ) ;
107+ process . exit ( 1 ) ; // 非零退出表示错误
108+ }
109+ }
110+
64111function main ( ) {
65112 if ( argv . all ) {
66- // compile all: yarn antlr4 --all
67- languageEntries . forEach ( ( language ) => {
68- compile ( language ) ;
69- } ) ;
113+ antlr4AllSql ( ) ;
70114 } else if ( argv . lang && typeof argv . lang === 'string' ) {
71115 // compile single: yarn antlr4 --lang=mysql
72116 const supportedLanguage = languageEntries . find ( ( language ) =>
73117 language . startsWith ( argv . lang )
74118 ) ;
75119
76120 if ( argv . lang === 'all' ) {
77- languageEntries . forEach ( ( language ) => {
78- compile ( language ) ;
79- } ) ;
121+ antlr4AllSql ( ) ;
80122 } else if ( supportedLanguage ) {
81123 compile ( supportedLanguage ) ;
82124 } else {
0 commit comments