11// This code is Deno only
22
3- import { parseDictionary } from "./parser.ts" ;
3+ // deno-lint-ignore-file no-console
4+
5+ import { ArrayResultError } from "../src/array_result.ts" ;
6+ import { PositionedError } from "../src/parser/parser_lib.ts" ;
7+ import { dictionaryParser } from "./parser.ts" ;
8+ import { Dictionary } from "./type.ts" ;
49
510const SOURCE = new URL ( "./dictionary" , import . meta. url ) ;
611const DESTINATION = new URL ( "./dictionary.ts" , import . meta. url ) ;
712
8- export async function build ( ) : Promise < void > {
9- // deno-lint-ignore no-console
10- console . log ( "Building dictionary..." ) ;
11- const text = await Deno . readTextFile ( SOURCE ) ;
13+ export async function buildWithDictionary (
14+ dictionary : Dictionary ,
15+ ) : Promise < void > {
1216 const json = JSON . stringify (
13- Object . fromEntries ( parseDictionary ( text ) ) ,
17+ Object . fromEntries ( dictionary ) ,
1418 undefined ,
1519 2 ,
1620 ) ;
@@ -22,9 +26,93 @@ import { Dictionary } from "./type.ts";
2226export const dictionary: Dictionary = new Map(Object.entries(${ json } ));
2327` ;
2428 await Deno . writeTextFile ( DESTINATION , code ) ;
25- // deno-lint-ignore no-console
26- console . log ( "Building dictionary done" ) ;
29+ }
30+ export async function build ( ) : Promise < boolean > {
31+ console . log ( "Building dictionary..." ) ;
32+ const start = performance . now ( ) ;
33+ const text = await Deno . readTextFile ( SOURCE ) ;
34+ const startDictionary = performance . now ( ) ;
35+ const result = dictionaryParser . parse ( text ) ;
36+ const endDictionary = performance . now ( ) ;
37+ let dictionary : Dictionary ;
38+ if ( ! result . isError ( ) ) {
39+ dictionary = result . array [ 0 ] ;
40+ } else {
41+ displayError ( text , result . errors ) ;
42+ return false ;
43+ }
44+ await buildWithDictionary ( dictionary ) ;
45+ const end = performance . now ( ) ;
46+ const total = Math . floor ( end - start ) ;
47+ const parsing = Math . floor ( endDictionary - startDictionary ) ;
48+ console . log (
49+ `Building dictionary done in ${ total } ms (parsing dictionary took ${ parsing } ms)` ,
50+ ) ;
51+ return true ;
52+ }
53+ function displayError (
54+ source : string ,
55+ errors : ReadonlyArray < ArrayResultError > ,
56+ ) : void {
57+ let color : boolean ;
58+ try {
59+ color = Deno . env . get ( "NO_COLOR" ) !== "1" ;
60+ } catch ( error ) {
61+ if ( error instanceof Deno . errors . NotCapable ) {
62+ color = true ;
63+ } else {
64+ throw error ;
65+ }
66+ }
67+ const red = color ? "color: red" : "" ;
68+ const sourceStyle = color ? "color: blue" : "" ;
69+ for ( const error of errors ) {
70+ console . error ( `%cError%c: ${ error . message } ` , red , "" ) ;
71+ if ( error instanceof PositionedError && error . position != null ) {
72+ const { position, length } = error . position ;
73+ const end = position + length ;
74+ // The only instance returning -1 is useful
75+ const startLine = source . lastIndexOf ( "\n" , position ) + 1 ;
76+ let currentLine = startLine ;
77+ let currentPosition = position ;
78+
79+ while ( true ) {
80+ const index = source . indexOf ( "\n" , currentLine ) ;
81+ const nextLine = index === - 1 ? source . length : index + 1 ;
82+ const line = source . slice ( currentLine , nextLine ) . trimEnd ( ) ;
83+ console . error ( line ) ;
84+ let relativeStart = Math . min (
85+ currentPosition - currentLine ,
86+ line . length ,
87+ ) ;
88+ let relativeEnd = Math . min ( end - currentLine , line . length ) ;
89+ if ( relativeEnd - relativeStart === 0 ) {
90+ if ( relativeStart !== 0 ) {
91+ relativeStart -- ;
92+ }
93+ if ( relativeEnd !== line . length ) {
94+ relativeEnd ++ ;
95+ }
96+ }
97+ console . error (
98+ `${ " " . repeat ( relativeStart ) } %c${
99+ "^" . repeat ( relativeEnd - relativeStart )
100+ } `,
101+ red ,
102+ ) ;
103+ if ( end <= nextLine ) {
104+ break ;
105+ } else {
106+ currentLine = currentPosition = nextLine ;
107+ }
108+ }
109+ const line = source . slice ( 0 , startLine ) . match ( / \n / g) ?. length ?? 1 ;
110+ const column = position - startLine + 1 ;
111+ console . error ( ` at %c${ SOURCE } :${ line } :${ column } ` , sourceStyle ) ;
112+ console . error ( ) ;
113+ }
114+ }
27115}
28116if ( import . meta. main ) {
29- await build ( ) ;
117+ Deno . exitCode = await build ( ) ? 0 : 1 ;
30118}
0 commit comments