| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 fasta.kernel_target; | 5 library fasta.kernel_target; |
| 6 | 6 |
| 7 import 'dart:async' show Future; | 7 import 'dart:async' show Future; |
| 8 | 8 |
| 9 import 'dart:io' show File; | 9 import 'dart:io' show File; |
| 10 | 10 |
| 11 import 'package:front_end/file_system.dart'; | 11 import 'package:front_end/file_system.dart'; |
| 12 |
| 12 import 'package:kernel/ast.dart' | 13 import 'package:kernel/ast.dart' |
| 13 show | 14 show |
| 14 Arguments, | 15 Arguments, |
| 15 CanonicalName, | 16 CanonicalName, |
| 16 Class, | 17 Class, |
| 17 Constructor, | 18 Constructor, |
| 18 DartType, | 19 DartType, |
| 19 DynamicType, | 20 DynamicType, |
| 20 EmptyStatement, | 21 EmptyStatement, |
| 21 Expression, | 22 Expression, |
| 22 ExpressionStatement, | 23 ExpressionStatement, |
| 23 Field, | 24 Field, |
| 24 FieldInitializer, | 25 FieldInitializer, |
| 25 FunctionNode, | 26 FunctionNode, |
| 26 Initializer, | 27 Initializer, |
| 27 InvalidInitializer, | 28 InvalidInitializer, |
| 28 Library, | 29 Library, |
| 30 ListLiteral, |
| 29 Name, | 31 Name, |
| 30 NamedExpression, | 32 NamedExpression, |
| 31 NullLiteral, | 33 NullLiteral, |
| 32 ProcedureKind, | 34 ProcedureKind, |
| 33 Program, | 35 Program, |
| 34 Source, | 36 Source, |
| 35 StringLiteral, | 37 StringLiteral, |
| 36 SuperInitializer, | 38 SuperInitializer, |
| 37 Throw, | 39 Throw, |
| 38 TypeParameter, | 40 TypeParameter, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 KernelTarget( | 104 KernelTarget( |
| 103 this.fileSystem, DillTarget dillTarget, TranslateUri uriTranslator, | 105 this.fileSystem, DillTarget dillTarget, TranslateUri uriTranslator, |
| 104 [Map<String, Source> uriToSource]) | 106 [Map<String, Source> uriToSource]) |
| 105 : dillTarget = dillTarget, | 107 : dillTarget = dillTarget, |
| 106 uriToSource = uriToSource ?? CompilerContext.current.uriToSource, | 108 uriToSource = uriToSource ?? CompilerContext.current.uriToSource, |
| 107 super(dillTarget.ticker, uriTranslator, dillTarget.backendTarget) { | 109 super(dillTarget.ticker, uriTranslator, dillTarget.backendTarget) { |
| 108 resetCrashReporting(); | 110 resetCrashReporting(); |
| 109 loader = createLoader(); | 111 loader = createLoader(); |
| 110 } | 112 } |
| 111 | 113 |
| 112 bool get hasErrors { | |
| 113 return errors.isNotEmpty || loader.collectCompileTimeErrors().isNotEmpty; | |
| 114 } | |
| 115 | |
| 116 void addError(file, int charOffset, String message) { | 114 void addError(file, int charOffset, String message) { |
| 117 Uri uri = file is String ? Uri.parse(file) : file; | 115 Uri uri = file is String ? Uri.parse(file) : file; |
| 118 InputError error = new InputError(uri, charOffset, message); | 116 InputError error = new InputError(uri, charOffset, message); |
| 119 String formatterMessage = error.format(); | 117 String formatterMessage = error.format(); |
| 120 print(formatterMessage); | 118 print(formatterMessage); |
| 121 errors.add(formatterMessage); | 119 errors.add(formatterMessage); |
| 122 } | 120 } |
| 123 | 121 |
| 124 SourceLoader<Library> createLoader() => | 122 SourceLoader<Library> createLoader() => |
| 125 new SourceLoader<Library>(fileSystem, this); | 123 new SourceLoader<Library>(fileSystem, this); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 handleInputError(null, | 276 handleInputError(null, |
| 279 isFullProgram: true, trimDependencies: trimDependencies); | 277 isFullProgram: true, trimDependencies: trimDependencies); |
| 280 return program; | 278 return program; |
| 281 } | 279 } |
| 282 | 280 |
| 283 try { | 281 try { |
| 284 await loader.buildBodies(); | 282 await loader.buildBodies(); |
| 285 loader.finishStaticInvocations(); | 283 loader.finishStaticInvocations(); |
| 286 finishAllConstructors(); | 284 finishAllConstructors(); |
| 287 loader.finishNativeMethods(); | 285 loader.finishNativeMethods(); |
| 288 if (!hasErrors) { | 286 runBuildTransformations(); |
| 289 runBuildTransformations(); | |
| 290 } | |
| 291 | 287 |
| 292 if (verify) this.verify(); | 288 if (verify) this.verify(); |
| 293 errors.addAll(loader.collectCompileTimeErrors().map((e) => e.format())); | |
| 294 if (errors.isNotEmpty) { | 289 if (errors.isNotEmpty) { |
| 295 handleInputError(null, | 290 handleInputError(null, |
| 296 isFullProgram: true, trimDependencies: trimDependencies); | 291 isFullProgram: true, trimDependencies: trimDependencies); |
| 297 } | 292 } |
| 293 handleRecoverableErrors(loader.unhandledErrors); |
| 298 } on InputError catch (e) { | 294 } on InputError catch (e) { |
| 299 handleInputError(e, | 295 handleInputError(e, |
| 300 isFullProgram: true, trimDependencies: trimDependencies); | 296 isFullProgram: true, trimDependencies: trimDependencies); |
| 301 } catch (e, s) { | 297 } catch (e, s) { |
| 302 return reportCrash(e, s, loader?.currentUriForCrashReporting); | 298 return reportCrash(e, s, loader?.currentUriForCrashReporting); |
| 303 } | 299 } |
| 304 if (trimDependencies) trimDependenciesInProgram(); | 300 if (trimDependencies) trimDependenciesInProgram(); |
| 305 return program; | 301 return program; |
| 306 } | 302 } |
| 307 | 303 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 } | 338 } |
| 343 for (String path in allDependencies) { | 339 for (String path in allDependencies) { |
| 344 sb.write(" "); | 340 sb.write(" "); |
| 345 sb.write(path); | 341 sb.write(path); |
| 346 } | 342 } |
| 347 sb.writeln(); | 343 sb.writeln(); |
| 348 await new File.fromUri(depsFile).writeAsString("$sb"); | 344 await new File.fromUri(depsFile).writeAsString("$sb"); |
| 349 ticker.logMs("Wrote deps file"); | 345 ticker.logMs("Wrote deps file"); |
| 350 } | 346 } |
| 351 | 347 |
| 348 /// Adds a synthetic field named `#errors` to the main library that contains |
| 349 /// [recoverableErrors] formatted. |
| 350 /// |
| 351 /// If [recoverableErrors] is empty, this method does nothing. |
| 352 /// |
| 353 /// If there's no main library, this method uses [erroneousProgram] to |
| 354 /// replace [program]. |
| 355 void handleRecoverableErrors(List<InputError> recoverableErrors) { |
| 356 if (recoverableErrors.isEmpty) return; |
| 357 KernelLibraryBuilder mainLibrary = loader.first; |
| 358 if (mainLibrary == null) { |
| 359 program = erroneousProgram(true); |
| 360 return; |
| 361 } |
| 362 List<Expression> expressions = <Expression>[]; |
| 363 for (InputError error in recoverableErrors) { |
| 364 String message = error.format(); |
| 365 errors.add(message); |
| 366 expressions.add(new StringLiteral(message)); |
| 367 } |
| 368 mainLibrary.library.addMember(new Field(new Name("#errors"), |
| 369 initializer: new ListLiteral(expressions, isConst: true), |
| 370 isConst: true)); |
| 371 } |
| 372 |
| 352 Program erroneousProgram(bool isFullProgram) { | 373 Program erroneousProgram(bool isFullProgram) { |
| 353 Uri uri = loader.first?.uri ?? Uri.parse("error:error"); | 374 Uri uri = loader.first?.uri ?? Uri.parse("error:error"); |
| 354 Uri fileUri = loader.first?.fileUri ?? uri; | 375 Uri fileUri = loader.first?.fileUri ?? uri; |
| 355 KernelLibraryBuilder library = | 376 KernelLibraryBuilder library = |
| 356 new KernelLibraryBuilder(uri, fileUri, loader, false); | 377 new KernelLibraryBuilder(uri, fileUri, loader, false); |
| 357 loader.first = library; | 378 loader.first = library; |
| 358 if (isFullProgram) { | 379 if (isFullProgram) { |
| 359 // If this is an outline, we shouldn't add an executable main | 380 // If this is an outline, we shouldn't add an executable main |
| 360 // method. Similarly considerations apply to separate compilation. It | 381 // method. Similarly considerations apply to separate compilation. It |
| 361 // could also make sense to add a way to mark .dill files as having | 382 // could also make sense to add a way to mark .dill files as having |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 } | 726 } |
| 706 for (Constructor constructor in superclass.constructors) { | 727 for (Constructor constructor in superclass.constructors) { |
| 707 if (constructor.name.name.isEmpty) { | 728 if (constructor.name.name.isEmpty) { |
| 708 return constructor.function.requiredParameterCount == 0 | 729 return constructor.function.requiredParameterCount == 0 |
| 709 ? constructor | 730 ? constructor |
| 710 : null; | 731 : null; |
| 711 } | 732 } |
| 712 } | 733 } |
| 713 return null; | 734 return null; |
| 714 } | 735 } |
| OLD | NEW |