| 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, IOSink; | 9 import 'dart:io' show File, IOSink; |
| 10 | 10 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 | 107 |
| 108 KernelTarget(DillTarget dillTarget, TranslateUri uriTranslator, | 108 KernelTarget(DillTarget dillTarget, TranslateUri uriTranslator, |
| 109 [Map<String, Source> uriToSource]) | 109 [Map<String, Source> uriToSource]) |
| 110 : dillTarget = dillTarget, | 110 : dillTarget = dillTarget, |
| 111 uriToSource = uriToSource ?? CompilerContext.current.uriToSource, | 111 uriToSource = uriToSource ?? CompilerContext.current.uriToSource, |
| 112 super(dillTarget.ticker, uriTranslator) { | 112 super(dillTarget.ticker, uriTranslator) { |
| 113 resetCrashReporting(); | 113 resetCrashReporting(); |
| 114 loader = createLoader(); | 114 loader = createLoader(); |
| 115 } | 115 } |
| 116 | 116 |
| 117 void addError(file, int charOffset, String message) { |
| 118 Uri uri = file is String ? Uri.parse(file) : file; |
| 119 InputError error = new InputError(uri, charOffset, message); |
| 120 print(error.format()); |
| 121 errors.add(error); |
| 122 } |
| 123 |
| 117 SourceLoader<Library> createLoader() => new SourceLoader<Library>(this); | 124 SourceLoader<Library> createLoader() => new SourceLoader<Library>(this); |
| 118 | 125 |
| 119 void addSourceInformation( | 126 void addSourceInformation( |
| 120 Uri uri, List<int> lineStarts, List<int> sourceCode) { | 127 Uri uri, List<int> lineStarts, List<int> sourceCode) { |
| 121 String fileUri = relativizeUri(uri); | 128 String fileUri = relativizeUri(uri); |
| 122 uriToSource[fileUri] = new Source(lineStarts, sourceCode); | 129 uriToSource[fileUri] = new Source(lineStarts, sourceCode); |
| 123 } | 130 } |
| 124 | 131 |
| 125 void read(Uri uri) { | 132 void read(Uri uri) { |
| 126 loader.read(uri); | 133 loader.read(uri); |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 ticker.logMs("Finished constructors"); | 551 ticker.logMs("Finished constructors"); |
| 545 } | 552 } |
| 546 | 553 |
| 547 /// Ensure constructors of [cls] have the correct initializers and other | 554 /// Ensure constructors of [cls] have the correct initializers and other |
| 548 /// requirements. | 555 /// requirements. |
| 549 void finishConstructors(Class cls) { | 556 void finishConstructors(Class cls) { |
| 550 /// Quotes below are from [Dart Programming Language Specification, 4th | 557 /// Quotes below are from [Dart Programming Language Specification, 4th |
| 551 /// Edition](http://www.ecma-international.org/publications/files/ECMA-ST/EC
MA-408.pdf): | 558 /// Edition](http://www.ecma-international.org/publications/files/ECMA-ST/EC
MA-408.pdf): |
| 552 Constructor superTarget; | 559 Constructor superTarget; |
| 553 List<Field> uninitializedFields = <Field>[]; | 560 List<Field> uninitializedFields = <Field>[]; |
| 561 List<Field> nonFinalFields = <Field>[]; |
| 554 for (Field field in cls.fields) { | 562 for (Field field in cls.fields) { |
| 563 if (field.isInstanceMember && !field.isFinal) { |
| 564 nonFinalFields.add(field); |
| 565 } |
| 555 if (field.initializer == null) { | 566 if (field.initializer == null) { |
| 556 uninitializedFields.add(field); | 567 uninitializedFields.add(field); |
| 557 } | 568 } |
| 558 } | 569 } |
| 559 Map<Constructor, List<FieldInitializer>> fieldInitializers = | 570 Map<Constructor, List<FieldInitializer>> fieldInitializers = |
| 560 <Constructor, List<FieldInitializer>>{}; | 571 <Constructor, List<FieldInitializer>>{}; |
| 561 for (Constructor constructor in cls.constructors) { | 572 for (Constructor constructor in cls.constructors) { |
| 562 if (!isRedirectingGenerativeConstructor(constructor)) { | 573 if (!isRedirectingGenerativeConstructor(constructor)) { |
| 563 /// >If no superinitializer is provided, an implicit superinitializer | 574 /// >If no superinitializer is provided, an implicit superinitializer |
| 564 /// >of the form super() is added at the end of k’s initializer list, | 575 /// >of the form super() is added at the end of k’s initializer list, |
| 565 /// >unless the enclosing class is class Object. | 576 /// >unless the enclosing class is class Object. |
| 566 if (!constructor.initializers.any(isSuperinitializerOrInvalid)) { | 577 if (!constructor.initializers.any(isSuperinitializerOrInvalid)) { |
| 567 superTarget ??= defaultSuperConstructor(cls); | 578 superTarget ??= defaultSuperConstructor(cls); |
| 568 Initializer initializer; | 579 Initializer initializer; |
| 569 if (superTarget == null) { | 580 if (superTarget == null) { |
| 570 Uri uri = constructor.enclosingClass.fileUri == null | 581 addError( |
| 571 ? null | 582 constructor.enclosingClass.fileUri, |
| 572 : Uri.parse(constructor.enclosingClass.fileUri); | |
| 573 InputError error = new InputError( | |
| 574 uri, | |
| 575 constructor.fileOffset, | 583 constructor.fileOffset, |
| 576 "${cls.superclass.name} has no constructor that takes zero" | 584 "${cls.superclass.name} has no constructor that takes zero" |
| 577 " arguments."); | 585 " arguments."); |
| 578 print(error.format()); | |
| 579 errors.add(error); | |
| 580 initializer = new InvalidInitializer(); | 586 initializer = new InvalidInitializer(); |
| 581 } else { | 587 } else { |
| 582 initializer = | 588 initializer = |
| 583 new SuperInitializer(superTarget, new Arguments.empty()); | 589 new SuperInitializer(superTarget, new Arguments.empty()); |
| 584 } | 590 } |
| 585 constructor.initializers.add(initializer); | 591 constructor.initializers.add(initializer); |
| 586 initializer.parent = constructor; | 592 initializer.parent = constructor; |
| 587 } | 593 } |
| 588 if (constructor.function.body == null) { | 594 if (constructor.function.body == null) { |
| 589 /// >If a generative constructor c is not a redirecting constructor | 595 /// >If a generative constructor c is not a redirecting constructor |
| 590 /// >and no body is provided, then c implicitly has an empty body {}. | 596 /// >and no body is provided, then c implicitly has an empty body {}. |
| 591 /// We use an empty statement instead. | 597 /// We use an empty statement instead. |
| 592 constructor.function.body = new EmptyStatement(); | 598 constructor.function.body = new EmptyStatement(); |
| 593 constructor.function.body.parent = constructor.function; | 599 constructor.function.body.parent = constructor.function; |
| 594 } | 600 } |
| 595 List<FieldInitializer> myFieldInitializers = <FieldInitializer>[]; | 601 List<FieldInitializer> myFieldInitializers = <FieldInitializer>[]; |
| 596 for (Initializer initializer in constructor.initializers) { | 602 for (Initializer initializer in constructor.initializers) { |
| 597 if (initializer is FieldInitializer) { | 603 if (initializer is FieldInitializer) { |
| 598 myFieldInitializers.add(initializer); | 604 myFieldInitializers.add(initializer); |
| 599 } | 605 } |
| 600 } | 606 } |
| 601 fieldInitializers[constructor] = myFieldInitializers; | 607 fieldInitializers[constructor] = myFieldInitializers; |
| 608 if (constructor.isConst && nonFinalFields.isNotEmpty) { |
| 609 addError(constructor.enclosingClass.fileUri, constructor.fileOffset, |
| 610 "Constructor is marked 'const' so all fields must be final."); |
| 611 for (Field field in nonFinalFields) { |
| 612 addError(constructor.enclosingClass.fileUri, field.fileOffset, |
| 613 "Field isn't final, but constructor is 'const'."); |
| 614 } |
| 615 nonFinalFields.clear(); |
| 616 } |
| 602 } | 617 } |
| 603 } | 618 } |
| 604 Set<Field> initializedFields; | 619 Set<Field> initializedFields; |
| 605 fieldInitializers.forEach( | 620 fieldInitializers.forEach( |
| 606 (Constructor constructor, List<FieldInitializer> initializers) { | 621 (Constructor constructor, List<FieldInitializer> initializers) { |
| 607 Iterable<Field> fields = initializers.map((i) => i.field); | 622 Iterable<Field> fields = initializers.map((i) => i.field); |
| 608 if (initializedFields == null) { | 623 if (initializedFields == null) { |
| 609 initializedFields = new Set<Field>.from(fields); | 624 initializedFields = new Set<Field>.from(fields); |
| 610 } else { | 625 } else { |
| 611 initializedFields.addAll(fields); | 626 initializedFields.addAll(fields); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 } | 699 } |
| 685 for (Constructor constructor in superclass.constructors) { | 700 for (Constructor constructor in superclass.constructors) { |
| 686 if (constructor.name.name.isEmpty) { | 701 if (constructor.name.name.isEmpty) { |
| 687 return constructor.function.requiredParameterCount == 0 | 702 return constructor.function.requiredParameterCount == 0 |
| 688 ? constructor | 703 ? constructor |
| 689 : null; | 704 : null; |
| 690 } | 705 } |
| 691 } | 706 } |
| 692 return null; | 707 return null; |
| 693 } | 708 } |
| OLD | NEW |