11
11
* @module cli/asc
12
12
*/
13
13
14
+ // Use "." instead of "/" as cwd in browsers
15
+ if ( process . browser ) process . cwd = function ( ) { return "." ; } ;
16
+
14
17
const fs = require ( "fs" ) ;
15
18
const path = require ( "path" ) ;
16
19
const utf8 = require ( "@protobufjs/utf8" ) ;
17
- const colors = require ( "./util/colors" ) ;
20
+ const colorsUtil = require ( "./util/colors" ) ;
21
+ const optionsUtil = require ( "./util/options" ) ;
18
22
const EOL = process . platform === "win32" ? "\r\n" : "\n" ;
19
23
20
24
// Use distribution files if present, otherwise run the sources directly
21
- var assemblyscript , isDev ;
25
+ var assemblyscript , isDev = false ;
22
26
( ( ) => {
23
27
try {
24
28
assemblyscript = require ( "../dist/assemblyscript.js" ) ;
25
- isDev = false ;
26
29
} catch ( e ) {
27
30
try {
28
- require ( "ts-node" ) . register ( {
29
- project : path . join ( __dirname , ".." , "src" , "tsconfig.json" ) ,
30
- files : [ // see: https://github.com/TypeStrong/ts-node/issues/620
31
- path . join ( __dirname , ".." , "std" , "portable.d.ts" ) ,
32
- path . join ( __dirname , ".." , "src" , "glue" , "binaryen.d.ts" )
33
- ]
34
- } ) ;
31
+ require ( "ts-node" ) . register ( { project : path . join ( __dirname , ".." , "src" , "tsconfig.json" ) } ) ;
35
32
require ( "../src/glue/js" ) ;
36
33
assemblyscript = require ( "../src" ) ;
37
34
isDev = true ;
38
35
} catch ( e ) {
39
36
// last resort: same directory CommonJS
40
37
assemblyscript = eval ( "require('./assemblyscript')" ) ;
41
- isDev = false ;
42
38
}
43
39
}
44
40
} ) ( ) ;
@@ -70,7 +66,7 @@ exports.defaultShrinkLevel = 1;
70
66
/** Bundled library files. */
71
67
exports . libraryFiles = exports . isBundle ? BUNDLE_LIBRARY : ( ( ) => { // set up if not a bundle
72
68
const libDir = path . join ( __dirname , ".." , "std" , "assembly" ) ;
73
- const libFiles = require ( "glob" ) . sync ( "**/* .ts" , { cwd : libDir } ) ;
69
+ const libFiles = require ( "glob" ) . sync ( "**/!(*.d) .ts" , { cwd : libDir } ) ;
74
70
const bundled = { } ;
75
71
libFiles . forEach ( file => bundled [ file . replace ( / \. t s $ / , "" ) ] = fs . readFileSync ( path . join ( libDir , file ) , "utf8" ) ) ;
76
72
return bundled ;
@@ -80,8 +76,8 @@ exports.libraryFiles = exports.isBundle ? BUNDLE_LIBRARY : (() => { // set up if
80
76
exports . definitionFiles = exports . isBundle ? BUNDLE_DEFINITIONS : ( ( ) => { // set up if not a bundle
81
77
const stdDir = path . join ( __dirname , ".." , "std" ) ;
82
78
return {
83
- "assembly" : fs . readFileSync ( path . join ( stdDir , "assembly.d.ts" ) , "utf8" ) ,
84
- "portable" : fs . readFileSync ( path . join ( stdDir , "portable.d.ts" ) , "utf8" )
79
+ "assembly" : fs . readFileSync ( path . join ( stdDir , "assembly" , "index .d.ts") , "utf8" ) ,
80
+ "portable" : fs . readFileSync ( path . join ( stdDir , "portable" , "index .d.ts") , "utf8" )
85
81
} ;
86
82
} ) ( ) ;
87
83
@@ -94,12 +90,16 @@ exports.compileString = (sources, options) => {
94
90
binary : null ,
95
91
text : null
96
92
} ) ;
97
- exports . main ( [
93
+ var argv = [
98
94
"--binaryFile" , "binary" ,
99
95
"--textFile" , "text" ,
100
- ...Object . keys ( options || { } ) . map ( arg => `--${ arg } =${ options [ arg ] } ` ) ,
101
- ...Object . keys ( sources ) ,
102
- ] , {
96
+ ] ;
97
+ Object . keys ( options || { } ) . forEach ( key => {
98
+ var val = options [ key ] ;
99
+ if ( Array . isArray ( val ) ) val . forEach ( val => argv . push ( "--" + key , String ( val ) ) ) ;
100
+ else argv . push ( "--" + key , String ( val ) ) ;
101
+ } ) ;
102
+ exports . main ( argv . concat ( Object . keys ( sources ) ) , {
103
103
stdout : output . stdout ,
104
104
stderr : output . stderr ,
105
105
readFile : name => sources . hasOwnProperty ( name ) ? sources [ name ] : null ,
@@ -129,22 +129,34 @@ exports.main = function main(argv, options, callback) {
129
129
if ( ! stdout ) throw Error ( "'options.stdout' must be specified" ) ;
130
130
if ( ! stderr ) throw Error ( "'options.stderr' must be specified" ) ;
131
131
132
- const args = parseArguments ( argv ) ;
133
- const indent = 24 ;
134
-
132
+ const opts = optionsUtil . parse ( argv , exports . options ) ;
133
+ const args = opts . options ;
134
+ argv = opts . arguments ;
135
135
if ( args . noColors ) {
136
- colors . stdout . supported =
137
- colors . stderr . supported = false ;
136
+ colorsUtil . stdout . supported =
137
+ colorsUtil . stderr . supported = false ;
138
138
} else {
139
- colors . stdout = colors . from ( stdout ) ;
140
- colors . stderr = colors . from ( stderr ) ;
139
+ colorsUtil . stdout = colorsUtil . from ( stdout ) ;
140
+ colorsUtil . stderr = colorsUtil . from ( stderr ) ;
141
+ }
142
+
143
+ // Check for unknown arguments
144
+ if ( opts . unknown . length ) {
145
+ opts . unknown . forEach ( arg => {
146
+ stderr . write ( colorsUtil . stderr . yellow ( "WARN: " ) + "Unknown option '" + arg + "'" + EOL ) ;
147
+ } ) ;
148
+ }
149
+
150
+ // Check for trailing arguments
151
+ if ( opts . trailing . length ) {
152
+ stderr . write ( colorsUtil . stderr . yellow ( "WARN: " ) + "Unsupported trailing arguments: " + opts . trailing . join ( " " ) + EOL ) ;
141
153
}
142
154
143
155
// Use default callback if none is provided
144
156
if ( ! callback ) callback = function defaultCallback ( err ) {
145
157
var code = 0 ;
146
158
if ( err ) {
147
- stderr . write ( colors . stderr . red ( "ERROR: " ) + err . stack . replace ( / ^ E R R O R : / i, "" ) + EOL ) ;
159
+ stderr . write ( colorsUtil . stderr . red ( "ERROR: " ) + err . stack . replace ( / ^ E R R O R : / i, "" ) + EOL ) ;
148
160
code = 1 ;
149
161
}
150
162
return code ;
@@ -156,43 +168,22 @@ exports.main = function main(argv, options, callback) {
156
168
return callback ( null ) ;
157
169
}
158
170
// Print the help message if requested or no source files are provided
159
- if ( args . help || args . _ . length < 1 ) {
160
- const opts = [ ] ;
161
- Object . keys ( exports . options ) . forEach ( name => {
162
- var option = exports . options [ name ] ;
163
- var text = " " ;
164
- text += "--" + name ;
165
- if ( option . aliases && option . aliases [ 0 ] . length === 1 ) {
166
- text += ", -" + option . aliases [ 0 ] ;
167
- }
168
- while ( text . length < indent ) {
169
- text += " " ;
170
- }
171
- if ( Array . isArray ( option . description ) ) {
172
- opts . push ( text + option . description [ 0 ] + option . description . slice ( 1 ) . map ( line => {
173
- for ( let i = 0 ; i < indent ; ++ i ) {
174
- line = " " + line ;
175
- }
176
- return EOL + line ;
177
- } ) . join ( "" ) ) ;
178
- } else {
179
- opts . push ( text + option . description ) ;
180
- }
181
- } ) ;
182
-
171
+ if ( args . help || ! argv . length ) {
183
172
var out = args . help ? stdout : stderr ;
184
- var color = args . help ? colors . stdout : colors . stderr ;
173
+ var color = args . help ? colorsUtil . stdout : colorsUtil . stderr ;
185
174
out . write ( [
186
- color . white ( "Syntax " ) ,
175
+ color . white ( "SYNTAX " ) ,
187
176
" " + color . cyan ( "asc" ) + " [entryFile ...] [options]" ,
188
177
"" ,
189
- color . white ( "Examples " ) ,
178
+ color . white ( "EXAMPLES " ) ,
190
179
" " + color . cyan ( "asc" ) + " hello.ts" ,
191
180
" " + color . cyan ( "asc" ) + " hello.ts -b hello.wasm -t hello.wat" ,
192
181
" " + color . cyan ( "asc" ) + " hello1.ts hello2.ts -b -O > hello.wasm" ,
193
182
"" ,
194
- color . white ( "Options" ) ,
195
- ] . concat ( opts ) . join ( EOL ) + EOL ) ;
183
+ color . white ( "OPTIONS" ) ,
184
+ ] . concat (
185
+ optionsUtil . help ( exports . options , 24 , EOL )
186
+ ) . join ( EOL ) + EOL ) ;
196
187
return callback ( null ) ;
197
188
}
198
189
@@ -209,7 +200,6 @@ exports.main = function main(argv, options, callback) {
209
200
// Set up transforms
210
201
const transforms = [ ] ;
211
202
if ( args . transform ) {
212
- if ( typeof args . transform === "string" ) args . transform = args . transform . split ( "," ) ;
213
203
args . transform . forEach ( transform =>
214
204
transforms . push (
215
205
require (
@@ -246,8 +236,9 @@ exports.main = function main(argv, options, callback) {
246
236
}
247
237
const customLibDirs = [ ] ;
248
238
if ( args . lib ) {
249
- if ( typeof args . lib === "string" ) args . lib = args . lib . split ( "," ) ;
250
- Array . prototype . push . apply ( customLibDirs , args . lib . map ( lib => lib . trim ( ) ) ) ;
239
+ let lib = args . lib ;
240
+ if ( typeof lib === "string" ) lib = lib . split ( "," ) ;
241
+ Array . prototype . push . apply ( customLibDirs , lib . map ( lib => lib . trim ( ) ) ) ;
251
242
for ( let i = 0 , k = customLibDirs . length ; i < k ; ++ i ) { // custom
252
243
let libDir = customLibDirs [ i ] ;
253
244
let libFiles ;
@@ -275,10 +266,10 @@ exports.main = function main(argv, options, callback) {
275
266
}
276
267
277
268
// Include entry files
278
- for ( let i = 0 , k = args . _ . length ; i < k ; ++ i ) {
279
- const filename = args . _ [ i ] ;
269
+ for ( let i = 0 , k = argv . length ; i < k ; ++ i ) {
270
+ const filename = argv [ i ] ;
280
271
281
- let sourcePath = filename . replace ( / \\ / g, "/" ) . replace ( / ( \. t s | \/ ) $ / , "" ) ;
272
+ let sourcePath = String ( filename ) . replace ( / \\ / g, "/" ) . replace ( / ( \. t s | \/ ) $ / , "" ) ;
282
273
283
274
// Try entryPath.ts, then entryPath/index.ts
284
275
let sourceText = readFile ( path . join ( baseDir , sourcePath ) + ".ts" ) ;
@@ -385,51 +376,28 @@ exports.main = function main(argv, options, callback) {
385
376
const program = assemblyscript . finishParsing ( parser ) ;
386
377
387
378
// Set up optimization levels
388
- var optimizeLevel = - 1 ;
379
+ var optimizeLevel = 0 ;
389
380
var shrinkLevel = 0 ;
390
- var debugInfo = ! args . noDebug ;
391
- if ( args . optimize !== false ) {
392
- if ( typeof args . optimize === "number" ) {
393
- optimizeLevel = args . optimize ;
394
- } else if ( args [ "0" ] ) {
395
- optimizeLevel = 0 ;
396
- } else if ( args [ "1" ] ) {
397
- optimizeLevel = 1 ;
398
- } else if ( args [ "2" ] ) {
399
- optimizeLevel = 2 ;
400
- } else if ( args [ "3" ] ) {
401
- optimizeLevel = 3 ;
402
- } else if ( args . optimize === true ) {
403
- optimizeLevel = exports . defaultOptimizeLevel ;
404
- shrinkLevel = exports . defaultShrinkLevel ;
405
- } else
406
- optimizeLevel = 0 ;
407
- }
408
- if ( args [ "s" ] ) {
409
- shrinkLevel = 1 ;
410
- } else if ( args [ "z" ] ) {
411
- shrinkLevel = 2 ;
381
+ if ( args . optimize ) {
382
+ optimizeLevel = exports . defaultOptimizeLevel ;
383
+ shrinkLevel = exports . defaultShrinkLevel ;
412
384
}
413
385
if ( typeof args . optimizeLevel === "number" ) {
414
386
optimizeLevel = args . optimizeLevel ;
415
387
}
416
388
if ( typeof args . shrinkLevel === "number" ) {
417
389
shrinkLevel = args . shrinkLevel ;
418
- } else if ( args . shrinkLevel === "s" ) {
419
- shrinkLevel = 1 ;
420
- } else if ( args . shrinkLevel === "z" ) {
421
- shrinkLevel = 2 ;
422
390
}
423
- optimizeLevel = Math . max ( optimizeLevel , 0 ) ;
424
- shrinkLevel = Math . max ( shrinkLevel , 0 ) ;
391
+ optimizeLevel = Math . min ( Math . max ( optimizeLevel , 0 ) , 3 ) ;
392
+ shrinkLevel = Math . min ( Math . max ( shrinkLevel , 0 ) , 2 ) ;
425
393
426
394
// Begin compilation
427
395
const compilerOptions = assemblyscript . createOptions ( ) ;
428
396
assemblyscript . setTarget ( compilerOptions , 0 ) ;
429
- assemblyscript . setNoTreeShaking ( compilerOptions , ! ! args . noTreeShaking ) ;
430
- assemblyscript . setNoAssert ( compilerOptions , ! ! args . noAssert ) ;
431
- assemblyscript . setImportMemory ( compilerOptions , ! ! args . importMemory ) ;
432
- assemblyscript . setImportTable ( compilerOptions , ! ! args . importTable ) ;
397
+ assemblyscript . setNoTreeShaking ( compilerOptions , args . noTreeShaking ) ;
398
+ assemblyscript . setNoAssert ( compilerOptions , args . noAssert ) ;
399
+ assemblyscript . setImportMemory ( compilerOptions , args . importMemory ) ;
400
+ assemblyscript . setImportTable ( compilerOptions , args . importTable ) ;
433
401
assemblyscript . setMemoryBase ( compilerOptions , args . memoryBase >>> 0 ) ;
434
402
assemblyscript . setSourceMap ( compilerOptions , args . sourceMap != null ) ;
435
403
assemblyscript . setOptimizeLevelHints ( compilerOptions , optimizeLevel , shrinkLevel ) ;
@@ -515,7 +483,7 @@ exports.main = function main(argv, options, callback) {
515
483
516
484
module . setOptimizeLevel ( optimizeLevel ) ;
517
485
module . setShrinkLevel ( shrinkLevel ) ;
518
- module . setDebugInfo ( debugInfo ) ;
486
+ module . setDebugInfo ( ! args . noDebug ) ;
519
487
520
488
var runPasses = [ ] ;
521
489
if ( args . runPasses ) {
@@ -741,7 +709,7 @@ exports.main = function main(argv, options, callback) {
741
709
var files ;
742
710
try {
743
711
stats . readTime += measure ( ( ) => {
744
- files = require ( "glob" ) . sync ( "* .ts" , { cwd : dirname } ) ;
712
+ files = require ( "glob" ) . sync ( "!(*.d) .ts" , { cwd : dirname } ) ;
745
713
} ) ;
746
714
return files ;
747
715
} catch ( e ) {
@@ -764,25 +732,23 @@ exports.main = function main(argv, options, callback) {
764
732
}
765
733
}
766
734
767
- /** Parses the specified command line arguments. */
768
- function parseArguments ( argv ) {
769
- const opts = { } ;
770
- Object . keys ( exports . options ) . forEach ( key => {
771
- const opt = exports . options [ key ] ;
772
- if ( opt . aliases ) {
773
- ( opts . alias || ( opts . alias = { } ) ) [ key ] = opt . aliases ;
774
- }
775
- if ( opt . default !== undefined ) {
776
- ( opts . default || ( opts . default = { } ) ) [ key ] = opt . default ;
777
- }
778
- if ( opt . type === "string" ) {
779
- ( opts . string || ( opts . string = [ ] ) ) . push ( key ) ;
780
- } else if ( opt . type === "boolean" ) {
781
- ( opts . boolean || ( opts . boolean = [ ] ) ) . push ( key ) ;
782
- }
783
- } ) ;
784
- return require ( "minimist" ) ( argv , opts ) ;
785
- }
735
+ var argumentSubstitutions = {
736
+ "-O" : [ "--optimize" ] ,
737
+ "-Os" : [ "--optimize" , "--shrinkLevel" , "1" ] ,
738
+ "-Oz" : [ "--optimize" , "--shrinkLevel" , "2" ] ,
739
+ "-O0" : [ "--optimizeLevel" , "0" , "--shrinkLevel" , "0" ] ,
740
+ "-O0s" : [ "--optimizeLevel" , "0" , "--shrinkLevel" , "1" ] ,
741
+ "-O0z" : [ "--optimizeLevel" , "0" , "--shrinkLevel" , "2" ] ,
742
+ "-O1" : [ "--optimizeLevel" , "1" , "--shrinkLevel" , "0" ] ,
743
+ "-O1s" : [ "--optimizeLevel" , "1" , "--shrinkLevel" , "1" ] ,
744
+ "-O1z" : [ "--optimizeLevel" , "1" , "--shrinkLevel" , "2" ] ,
745
+ "-O2" : [ "--optimizeLevel" , "2" , "--shrinkLevel" , "0" ] ,
746
+ "-O2s" : [ "--optimizeLevel" , "2" , "--shrinkLevel" , "1" ] ,
747
+ "-O2z" : [ "--optimizeLevel" , "2" , "--shrinkLevel" , "2" ] ,
748
+ "-O3" : [ "--optimizeLevel" , "3" , "--shrinkLevel" , "0" ] ,
749
+ "-O3s" : [ "--optimizeLevel" , "3" , "--shrinkLevel" , "1" ] ,
750
+ "-O3z" : [ "--optimizeLevel" , "3" , "--shrinkLevel" , "2" ] ,
751
+ } ;
786
752
787
753
/** Checks diagnostics emitted so far for errors. */
788
754
function checkDiagnostics ( emitter , stderr ) {
0 commit comments