| 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 |