OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #library('dart2js'); | |
6 | |
7 #import('dart:io'); | |
8 #import('dart:utf'); | |
9 | |
10 #import('../../lib/uri/uri.dart'); | |
11 #import('../../frog/leg/api.dart', prefix: 'api'); | |
12 #import('../../frog/leg/io/io.dart', prefix: 'io'); | |
13 #import('../../frog/leg/colors.dart'); | |
14 #import('source_file.dart'); | |
15 | |
16 String relativize(Uri base, Uri uri) { | |
17 if (base.scheme == 'file' && | |
18 base.scheme == uri.scheme && | |
19 base.userInfo == uri.userInfo && | |
20 base.domain == uri.domain && | |
21 base.port == uri.port && | |
22 uri.query == "" && uri.fragment == "") { | |
23 if (uri.path.startsWith(base.path)) { | |
24 return uri.path.substring(base.path.length); | |
25 } | |
26 List<String> uriParts = uri.path.split('/'); | |
27 List<String> baseParts = base.path.split('/'); | |
28 int common = 0; | |
29 int length = Math.min(uriParts.length, baseParts.length); | |
30 while (common < length && uriParts[common] == baseParts[common]) { | |
31 common++; | |
32 } | |
33 StringBuffer sb = new StringBuffer(); | |
34 for (int i = common + 1; i < baseParts.length; i++) { | |
35 sb.add('../'); | |
36 } | |
37 for (int i = common; i < uriParts.length - 1; i++) { | |
38 sb.add('${uriParts[i]}/'); | |
39 } | |
40 sb.add('${uriParts.last()}'); | |
41 return sb.toString(); | |
42 } | |
43 return uri.toString(); | |
44 } | |
45 | |
46 void compile(List<String> argv) { | |
47 Uri cwd = new Uri(scheme: 'file', path: io.getCurrentDirectory()); | |
48 bool throwOnError = false; | |
49 bool showWarnings = true; | |
50 bool verbose = false; | |
51 Uri libraryRoot = cwd; | |
52 Uri out = cwd.resolve('out.js'); | |
53 | |
54 List<String> arguments = <String>[]; | |
55 for (String argument in argv) { | |
56 if ('--throw-on-error' == argument) { | |
57 throwOnError = true; | |
58 } else if ('--suppress-warnings' == argument) { | |
59 showWarnings = false; | |
60 } else if ('--verbose' == argument) { | |
61 verbose = true; | |
62 } else if (argument.startsWith('--library-root=')) { | |
63 String path = argument.substring(argument.indexOf('=') + 1); | |
64 if (!path.endsWith("/")) path = "$path/"; | |
65 libraryRoot = cwd.resolve(path); | |
66 } else if (argument.startsWith('--out=')) { | |
67 String path = argument.substring(argument.indexOf('=') + 1); | |
68 out = cwd.resolve(path); | |
69 } else if (argument.startsWith('-')) { | |
70 throw new AbortLeg('unknown option $argument'); | |
71 } else { | |
72 arguments.add(argument); | |
73 } | |
74 } | |
75 if (arguments.isEmpty()) { | |
76 throw new AbortLeg('no files to compile'); | |
77 } | |
78 if (arguments.length > 1) { | |
79 var extra = arguments.getRange(1, arguments.length - 1); | |
80 throw new AbortLeg('extra arguments: $extra'); | |
81 } | |
82 | |
83 Map<String, SourceFile> sourceFiles = <SourceFile>{}; | |
84 int dartBytesRead = 0; | |
85 | |
86 Future<String> provider(Uri uri) { | |
87 if (uri.scheme != 'file') { | |
88 throw new IllegalArgumentException(uri); | |
89 } | |
90 String source = readAll(uri.path); | |
91 dartBytesRead += source.length; | |
92 sourceFiles[uri.toString()] = | |
93 new SourceFile(relativize(cwd, uri), source); | |
94 Completer<String> completer = new Completer<String>(); | |
95 completer.complete(source); | |
96 return completer.future; | |
97 } | |
98 | |
99 void info(var message) { | |
100 if (verbose) print('${green("info:")} $message'); | |
101 } | |
102 | |
103 void handler(Uri uri, int begin, int end, String message, bool fatal) { | |
104 if (uri === null && !fatal) { | |
105 info(message); | |
106 return; | |
107 } | |
108 if (uri === null) { | |
109 assert(fatal); | |
110 print(message); | |
111 } else if (fatal || showWarnings) { | |
112 SourceFile file = sourceFiles[uri.toString()]; | |
113 print(file.getLocationMessage(message, begin, end, true)); | |
114 } | |
115 if (fatal && throwOnError) throw new AbortLeg(message); | |
116 } | |
117 | |
118 Uri uri = cwd.resolve(arguments[0]); | |
119 info('compiling $uri'); | |
120 | |
121 // TODO(ahe): We expect the future to be complete and call value | |
122 // directly. In effect, we don't support truly asynchronous API. | |
123 String code = api.compile(uri, libraryRoot, provider, handler).value; | |
124 if (code === null) throw new AbortLeg('compilation failed'); | |
125 writeString(out, code); | |
126 int jsBytesWritten = code.length; | |
127 info('compiled $dartBytesRead bytes Dart -> $jsBytesWritten bytes JS ' | |
128 + 'in ${relativize(cwd, out)}'); | |
129 } | |
130 | |
131 class AbortLeg { | |
132 final message; | |
133 AbortLeg(this.message); | |
134 toString() => 'Aborted due to --throw-on-error: $message'; | |
135 } | |
136 | |
137 void writeString(Uri uri, String text) { | |
138 if (uri.scheme != 'file') { | |
139 throw new AbortLeg('unhandled scheme ${uri.scheme}'); | |
140 } | |
141 var file = new File(uri.path).openSync(FileMode.WRITE); | |
142 file.writeStringSync(text); | |
143 file.closeSync(); | |
144 } | |
145 | |
146 String readAll(String filename) { | |
147 var file = (new File(filename)).openSync(); | |
148 var length = file.lengthSync(); | |
149 var buffer = new List<int>(length); | |
150 var bytes = file.readListSync(buffer, 0, length); | |
151 file.closeSync(); | |
152 return new String.fromCharCodes(new Utf8Decoder(buffer).decodeRest()); | |
153 } | |
OLD | NEW |