1
1
// This code is Deno only
2
2
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" ;
4
9
5
10
const SOURCE = new URL ( "./dictionary" , import . meta. url ) ;
6
11
const DESTINATION = new URL ( "./dictionary.ts" , import . meta. url ) ;
7
12
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 > {
12
16
const json = JSON . stringify (
13
- Object . fromEntries ( parseDictionary ( text ) ) ,
17
+ Object . fromEntries ( dictionary ) ,
14
18
undefined ,
15
19
2 ,
16
20
) ;
@@ -22,9 +26,93 @@ import { Dictionary } from "./type.ts";
22
26
export const dictionary: Dictionary = new Map(Object.entries(${ json } ));
23
27
` ;
24
28
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
+ }
27
115
}
28
116
if ( import . meta. main ) {
29
- await build ( ) ;
117
+ Deno . exitCode = await build ( ) ? 0 : 1 ;
30
118
}
0 commit comments