OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library mirrors_dart2js; | 5 library mirrors_dart2js; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection' show LinkedHashMap; | 8 import 'dart:collection' show LinkedHashMap; |
9 import 'dart:io'; | 9 import 'dart:io'; |
10 import 'dart:uri'; | 10 import 'dart:uri'; |
11 | 11 |
12 import '../../compiler.dart' as diagnostics; | 12 import '../../compiler.dart' as api; |
13 import '../elements/elements.dart'; | 13 import '../elements/elements.dart'; |
14 import '../resolution/resolution.dart' show ResolverTask, ResolverVisitor; | 14 import '../resolution/resolution.dart' show ResolverTask, ResolverVisitor; |
15 import '../apiimpl.dart' show Compiler; | 15 import '../apiimpl.dart' show Compiler; |
16 import '../scanner/scannerlib.dart' hide SourceString; | 16 import '../scanner/scannerlib.dart' hide SourceString; |
17 import '../ssa/ssa.dart'; | 17 import '../ssa/ssa.dart'; |
18 import '../dart2jslib.dart' hide Compiler; | 18 import '../dart2jslib.dart' hide Compiler; |
19 import '../dart_types.dart'; | 19 import '../dart_types.dart'; |
20 import '../filenames.dart'; | 20 import '../filenames.dart'; |
21 import '../source_file.dart'; | 21 import '../source_file.dart'; |
22 import '../tree/tree.dart'; | 22 import '../tree/tree.dart'; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 } else if (type is FunctionType) { | 77 } else if (type is FunctionType) { |
78 return new Dart2JsFunctionTypeMirror(system, type, functionSignature); | 78 return new Dart2JsFunctionTypeMirror(system, type, functionSignature); |
79 } else if (type is VoidType) { | 79 } else if (type is VoidType) { |
80 return new Dart2JsVoidMirror(system, type); | 80 return new Dart2JsVoidMirror(system, type); |
81 } else if (type is TypedefType) { | 81 } else if (type is TypedefType) { |
82 return new Dart2JsTypedefMirror(system, type); | 82 return new Dart2JsTypedefMirror(system, type); |
83 } else if (type is MalformedType) { | 83 } else if (type is MalformedType) { |
84 // TODO(johnniwinther): We need a mirror on malformed types. | 84 // TODO(johnniwinther): We need a mirror on malformed types. |
85 return system.dynamicType; | 85 return system.dynamicType; |
86 } | 86 } |
87 _diagnosticListener.internalError( | |
88 "Unexpected type $type of kind ${type.kind}"); | |
89 system.compiler.internalError("Unexpected type $type of kind ${type.kind}"); | 87 system.compiler.internalError("Unexpected type $type of kind ${type.kind}"); |
90 } | 88 } |
91 | 89 |
92 Collection<Dart2JsMemberMirror> _convertElementMemberToMemberMirrors( | 90 Collection<Dart2JsMemberMirror> _convertElementMemberToMemberMirrors( |
93 Dart2JsContainerMirror library, Element element) { | 91 Dart2JsContainerMirror library, Element element) { |
94 if (element.isSynthesized) { | 92 if (element.isSynthesized) { |
95 return const <Dart2JsMemberMirror>[]; | 93 return const <Dart2JsMemberMirror>[]; |
96 } else if (element is VariableElement) { | 94 } else if (element is VariableElement) { |
97 return <Dart2JsMemberMirror>[new Dart2JsFieldMirror(library, element)]; | 95 return <Dart2JsMemberMirror>[new Dart2JsFieldMirror(library, element)]; |
98 } else if (element is FunctionElement) { | 96 } else if (element is FunctionElement) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 'xor': '^', | 184 'xor': '^', |
187 'or': '|', | 185 'or': '|', |
188 }; | 186 }; |
189 String newName = mapping[name]; | 187 String newName = mapping[name]; |
190 if (newName == null) { | 188 if (newName == null) { |
191 throw new Exception('Unhandled operator name: $name'); | 189 throw new Exception('Unhandled operator name: $name'); |
192 } | 190 } |
193 return newName; | 191 return newName; |
194 } | 192 } |
195 | 193 |
196 DiagnosticListener get _diagnosticListener { | |
197 return const Dart2JsDiagnosticListener(); | |
198 } | |
199 | |
200 class Dart2JsDiagnosticListener implements DiagnosticListener { | |
201 const Dart2JsDiagnosticListener(); | |
202 | |
203 void cancel(String reason, {node, token, instruction, element}) { | |
204 print(reason); | |
205 } | |
206 | |
207 void log(message) { | |
208 print(message); | |
209 } | |
210 | |
211 void internalError(String message, | |
212 {Node node, Token token, HInstruction instruction, | |
213 Element element}) { | |
214 cancel('Internal error: $message', node: node, token: token, | |
215 instruction: instruction, element: element); | |
216 } | |
217 | |
218 void internalErrorOnElement(Element element, String message) { | |
219 internalError(message, element: element); | |
220 } | |
221 | |
222 SourceSpan spanFromSpannable(Node node, [Uri uri]) { | |
223 // TODO(johnniwinther): implement this. | |
224 throw 'unimplemented'; | |
225 } | |
226 | |
227 void reportMessage(SourceSpan span, Diagnostic message, | |
228 diagnostics.Diagnostic kind) { | |
229 // TODO(johnniwinther): implement this. | |
230 throw 'unimplemented'; | |
231 } | |
232 | |
233 bool onDeprecatedFeature(Spannable span, String feature) { | |
234 // TODO(johnniwinther): implement this? | |
235 throw 'unimplemented'; | |
236 } | |
237 } | |
238 | |
239 //------------------------------------------------------------------------------ | 194 //------------------------------------------------------------------------------ |
240 // Compilation implementation | 195 // Compilation implementation |
241 //------------------------------------------------------------------------------ | 196 //------------------------------------------------------------------------------ |
242 | 197 |
243 // TODO(johnniwinther): Support client configurable handlers/providers. | 198 // TODO(johnniwinther): Support client configurable providers. |
244 class Dart2JsCompilation implements Compilation { | |
245 Compiler _compiler; | |
246 final Uri cwd; | |
247 final SourceFileProvider provider; | |
248 | 199 |
249 Dart2JsCompilation(Path script, Path libraryRoot, | 200 /** |
250 [Path packageRoot, List<String> opts = const <String>[]]) | 201 * Returns a future that completes to a non-null String when [script] |
251 : cwd = getCurrentDirectory(), | 202 * has been successfully compiled. |
252 provider = new SourceFileProvider() { | 203 * |
253 var handler = new FormattingDiagnosticHandler(provider); | 204 * TODO(johnniwinther): The method is deprecated but here to support [Path] |
254 var libraryUri = cwd.resolve('${libraryRoot}/'); | 205 * which is used through dartdoc. |
255 var packageUri; | 206 */ |
256 if (packageRoot != null) { | 207 Future<String> compile(Path script, |
257 packageUri = cwd.resolve('${packageRoot}/'); | 208 Path libraryRoot, |
258 } else { | 209 {Path packageRoot, |
259 packageUri = libraryUri; | 210 List<String> options: const <String>[], |
| 211 api.DiagnosticHandler diagnosticHandler}) { |
| 212 Uri cwd = getCurrentDirectory(); |
| 213 SourceFileProvider provider = new SourceFileProvider(); |
| 214 if (diagnosticHandler == null) { |
| 215 diagnosticHandler = |
| 216 new FormattingDiagnosticHandler(provider).diagnosticHandler; |
| 217 } |
| 218 Uri scriptUri = cwd.resolve(script.toString()); |
| 219 Uri libraryUri = cwd.resolve('${libraryRoot}/'); |
| 220 Uri packageUri = null; |
| 221 if (packageRoot != null) { |
| 222 packageUri = cwd.resolve('${packageRoot}/'); |
| 223 } |
| 224 return api.compile(scriptUri, libraryUri, packageUri, |
| 225 provider.readStringFromUri, diagnosticHandler, options); |
| 226 } |
| 227 |
| 228 /** |
| 229 * Analyzes set of libraries and provides a mirror system which can be used for |
| 230 * static inspection of the source code. |
| 231 */ |
| 232 Future<MirrorSystem> analyze(List<Path> libraries, |
| 233 Path libraryRoot, |
| 234 {Path packageRoot, |
| 235 List<String> options: const <String>[], |
| 236 api.DiagnosticHandler diagnosticHandler}) { |
| 237 Uri cwd = getCurrentDirectory(); |
| 238 SourceFileProvider provider = new SourceFileProvider(); |
| 239 if (diagnosticHandler == null) { |
| 240 diagnosticHandler = |
| 241 new FormattingDiagnosticHandler(provider).diagnosticHandler; |
| 242 } |
| 243 Uri libraryUri = cwd.resolve('${libraryRoot}/'); |
| 244 Uri packageUri = null; |
| 245 if (packageRoot != null) { |
| 246 packageUri = cwd.resolve('${packageRoot}/'); |
| 247 } |
| 248 options = new List<String>.from(options); |
| 249 options.add('--analyze-only'); |
| 250 options.add('--analyze-signatures-only'); |
| 251 options.add('--analyze-all'); |
| 252 |
| 253 bool compilationFailed = false; |
| 254 void internalDiagnosticHandler(Uri uri, int begin, int end, |
| 255 String message, api.Diagnostic kind) { |
| 256 if (kind == api.Diagnostic.ERROR || |
| 257 kind == api.Diagnostic.CRASH) { |
| 258 compilationFailed = true; |
260 } | 259 } |
261 _compiler = new Compiler(provider.readStringFromUri, | 260 diagnosticHandler(uri, begin, end, message, kind); |
262 null, | |
263 handler.diagnosticHandler, | |
264 libraryUri, packageUri, opts); | |
265 var scriptUri = cwd.resolve(script.toString()); | |
266 // TODO(johnniwinther): Detect file not found | |
267 _compiler.run(scriptUri); | |
268 } | 261 } |
269 | 262 |
270 Dart2JsCompilation.library(List<Path> libraries, Path libraryRoot, | 263 // TODO(johnniwinther): Extract the following as an [analyze] method in |
271 [Path packageRoot, List<String> opts = const <String>[]]) | 264 // [:compiler/compiler.dart:]. |
272 : cwd = getCurrentDirectory(), | 265 Compiler compiler = new Compiler(provider.readStringFromUri, |
273 provider = new SourceFileProvider() { | 266 null, |
274 var libraryUri = cwd.resolve('${libraryRoot}/'); | 267 internalDiagnosticHandler, |
275 var packageUri; | 268 libraryUri, packageUri, options); |
276 if (packageRoot != null) { | 269 List<Uri> librariesUri = <Uri>[]; |
277 packageUri = cwd.resolve('${packageRoot}/'); | 270 for (Path library in libraries) { |
278 } else { | 271 librariesUri.add(cwd.resolve(library.toString())); |
279 packageUri = libraryUri; | |
280 } | |
281 opts = new List<String>.from(opts); | |
282 opts.add('--analyze-signatures-only'); | |
283 opts.add('--analyze-all'); | |
284 _compiler = new Compiler(provider.readStringFromUri, | |
285 null, | |
286 silentDiagnosticHandler, | |
287 libraryUri, packageUri, opts); | |
288 var librariesUri = <Uri>[]; | |
289 for (Path library in libraries) { | |
290 librariesUri.add(cwd.resolve(library.toString())); | |
291 // TODO(johnniwinther): Detect file not found | |
292 } | |
293 _compiler.librariesToAnalyzeWhenRun = librariesUri; | |
294 _compiler.run(null); | |
295 } | 272 } |
296 | 273 compiler.librariesToAnalyzeWhenRun = librariesUri; |
297 MirrorSystem get mirrors => new Dart2JsMirrorSystem(_compiler); | 274 bool success = compiler.run(null); |
298 | 275 if (success && !compilationFailed) { |
299 Future<String> compileToJavaScript() => | 276 return new Future<MirrorSystem>.immediate( |
300 new Future<String>.immediate(_compiler.assembledCode); | 277 new Dart2JsMirrorSystem(compiler)); |
| 278 } else { |
| 279 return new Future<MirrorSystem>.immediateError( |
| 280 'Failed to create mirror system.'); |
| 281 } |
301 } | 282 } |
302 | 283 |
303 | |
304 //------------------------------------------------------------------------------ | 284 //------------------------------------------------------------------------------ |
305 // Dart2Js specific extensions of mirror interfaces | 285 // Dart2Js specific extensions of mirror interfaces |
306 //------------------------------------------------------------------------------ | 286 //------------------------------------------------------------------------------ |
307 | 287 |
308 abstract class Dart2JsMirror implements Mirror { | 288 abstract class Dart2JsMirror implements Mirror { |
309 Dart2JsMirrorSystem get mirrors; | 289 Dart2JsMirrorSystem get mirrors; |
310 } | 290 } |
311 | 291 |
312 abstract class Dart2JsDeclarationMirror extends Dart2JsMirror | 292 abstract class Dart2JsDeclarationMirror extends Dart2JsMirror |
313 implements DeclarationMirror { | 293 implements DeclarationMirror { |
(...skipping 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1733 return new Future.immediate( | 1713 return new Future.immediate( |
1734 new Dart2JsStringConstantMirror.fromString(mirrors, text)); | 1714 new Dart2JsStringConstantMirror.fromString(mirrors, text)); |
1735 } else if (fieldName == 'trimmedText') { | 1715 } else if (fieldName == 'trimmedText') { |
1736 return new Future.immediate( | 1716 return new Future.immediate( |
1737 new Dart2JsStringConstantMirror.fromString(mirrors, trimmedText)); | 1717 new Dart2JsStringConstantMirror.fromString(mirrors, trimmedText)); |
1738 } | 1718 } |
1739 // TODO(johnniwinther): Which exception/error should be thrown here? | 1719 // TODO(johnniwinther): Which exception/error should be thrown here? |
1740 throw new UnsupportedError('InstanceMirror does not have a reflectee'); | 1720 throw new UnsupportedError('InstanceMirror does not have a reflectee'); |
1741 } | 1721 } |
1742 } | 1722 } |
OLD | NEW |