| 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 12 matching lines...) Expand all Loading... |
| 23 FieldInitializer, | 23 FieldInitializer, |
| 24 FunctionNode, | 24 FunctionNode, |
| 25 Initializer, | 25 Initializer, |
| 26 InvalidInitializer, | 26 InvalidInitializer, |
| 27 Library, | 27 Library, |
| 28 Name, | 28 Name, |
| 29 NamedExpression, | 29 NamedExpression, |
| 30 NullLiteral, | 30 NullLiteral, |
| 31 ProcedureKind, | 31 ProcedureKind, |
| 32 Program, | 32 Program, |
| 33 RedirectingInitializer, | |
| 34 Source, | 33 Source, |
| 35 StringLiteral, | 34 StringLiteral, |
| 36 SuperInitializer, | 35 SuperInitializer, |
| 37 Throw, | 36 Throw, |
| 38 TypeParameter, | 37 TypeParameter, |
| 39 VariableDeclaration, | 38 VariableDeclaration, |
| 40 VariableGet, | 39 VariableGet, |
| 41 VoidType; | 40 VoidType; |
| 42 | 41 |
| 43 import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter; | 42 import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 import 'kernel_builder.dart' | 75 import 'kernel_builder.dart' |
| 77 show | 76 show |
| 78 Builder, | 77 Builder, |
| 79 ClassBuilder, | 78 ClassBuilder, |
| 80 InvalidTypeBuilder, | 79 InvalidTypeBuilder, |
| 81 KernelClassBuilder, | 80 KernelClassBuilder, |
| 82 KernelLibraryBuilder, | 81 KernelLibraryBuilder, |
| 83 KernelNamedTypeBuilder, | 82 KernelNamedTypeBuilder, |
| 84 KernelProcedureBuilder, | 83 KernelProcedureBuilder, |
| 85 LibraryBuilder, | 84 LibraryBuilder, |
| 85 MemberBuilder, |
| 86 MixinApplicationBuilder, | 86 MixinApplicationBuilder, |
| 87 NamedMixinApplicationBuilder, | 87 NamedMixinApplicationBuilder, |
| 88 NamedTypeBuilder, | 88 NamedTypeBuilder, |
| 89 TypeBuilder, | 89 TypeBuilder, |
| 90 TypeVariableBuilder; | 90 TypeVariableBuilder; |
| 91 | 91 |
| 92 import 'verifier.dart' show verifyProgram; | 92 import 'verifier.dart' show verifyProgram; |
| 93 | 93 |
| 94 class KernelTarget extends TargetImplementation { | 94 class KernelTarget extends TargetImplementation { |
| 95 final DillTarget dillTarget; | 95 final DillTarget dillTarget; |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 AsyncMarker.Sync, | 348 AsyncMarker.Sync, |
| 349 ProcedureKind.Method, | 349 ProcedureKind.Method, |
| 350 library, | 350 library, |
| 351 -1, | 351 -1, |
| 352 -1, | 352 -1, |
| 353 -1); | 353 -1); |
| 354 library.addBuilder(mainBuilder.name, mainBuilder, -1); | 354 library.addBuilder(mainBuilder.name, mainBuilder, -1); |
| 355 mainBuilder.body = new ExpressionStatement( | 355 mainBuilder.body = new ExpressionStatement( |
| 356 new Throw(new StringLiteral("${errors.join('\n')}"))); | 356 new Throw(new StringLiteral("${errors.join('\n')}"))); |
| 357 } | 357 } |
| 358 library.build(); | 358 library.build(loader.coreLibrary); |
| 359 return link(<Library>[library.library]); | 359 return link(<Library>[library.library]); |
| 360 } | 360 } |
| 361 | 361 |
| 362 /// Creates a program by combining [libraries] with the libraries of | 362 /// Creates a program by combining [libraries] with the libraries of |
| 363 /// `dillTarget.loader.program`. | 363 /// `dillTarget.loader.program`. |
| 364 Program link(List<Library> libraries) { | 364 Program link(List<Library> libraries) { |
| 365 Map<String, Source> uriToSource = | 365 Map<String, Source> uriToSource = |
| 366 new Map<String, Source>.from(this.uriToSource); | 366 new Map<String, Source>.from(this.uriToSource); |
| 367 | 367 |
| 368 final Program binary = dillTarget.loader.program; | 368 final Program binary = dillTarget.loader.program; |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 return new Constructor( | 555 return new Constructor( |
| 556 new FunctionNode(new EmptyStatement(), returnType: const VoidType()), | 556 new FunctionNode(new EmptyStatement(), returnType: const VoidType()), |
| 557 name: new Name("")); | 557 name: new Name("")); |
| 558 } | 558 } |
| 559 | 559 |
| 560 void finishAllConstructors() { | 560 void finishAllConstructors() { |
| 561 Class objectClass = this.objectClass; | 561 Class objectClass = this.objectClass; |
| 562 for (SourceClassBuilder builder in collectAllSourceClasses()) { | 562 for (SourceClassBuilder builder in collectAllSourceClasses()) { |
| 563 Class cls = builder.target; | 563 Class cls = builder.target; |
| 564 if (cls != objectClass) { | 564 if (cls != objectClass) { |
| 565 finishConstructors(cls); | 565 finishConstructors(builder); |
| 566 } | 566 } |
| 567 } | 567 } |
| 568 ticker.logMs("Finished constructors"); | 568 ticker.logMs("Finished constructors"); |
| 569 } | 569 } |
| 570 | 570 |
| 571 /// Ensure constructors of [cls] have the correct initializers and other | 571 /// Ensure constructors of [cls] have the correct initializers and other |
| 572 /// requirements. | 572 /// requirements. |
| 573 void finishConstructors(Class cls) { | 573 void finishConstructors(SourceClassBuilder builder) { |
| 574 Class cls = builder.target; |
| 575 |
| 574 /// Quotes below are from [Dart Programming Language Specification, 4th | 576 /// Quotes below are from [Dart Programming Language Specification, 4th |
| 575 /// Edition](http://www.ecma-international.org/publications/files/ECMA-ST/EC
MA-408.pdf): | 577 /// Edition](http://www.ecma-international.org/publications/files/ECMA-ST/EC
MA-408.pdf): |
| 576 Constructor superTarget; | |
| 577 List<Field> uninitializedFields = <Field>[]; | 578 List<Field> uninitializedFields = <Field>[]; |
| 578 List<Field> nonFinalFields = <Field>[]; | 579 List<Field> nonFinalFields = <Field>[]; |
| 579 for (Field field in cls.fields) { | 580 for (Field field in cls.fields) { |
| 580 if (field.isInstanceMember && !field.isFinal) { | 581 if (field.isInstanceMember && !field.isFinal) { |
| 581 nonFinalFields.add(field); | 582 nonFinalFields.add(field); |
| 582 } | 583 } |
| 583 if (field.initializer == null) { | 584 if (field.initializer == null) { |
| 584 uninitializedFields.add(field); | 585 uninitializedFields.add(field); |
| 585 } | 586 } |
| 586 } | 587 } |
| 587 Map<Constructor, List<FieldInitializer>> fieldInitializers = | 588 Map<Constructor, List<FieldInitializer>> fieldInitializers = |
| 588 <Constructor, List<FieldInitializer>>{}; | 589 <Constructor, List<FieldInitializer>>{}; |
| 589 for (Constructor constructor in cls.constructors) { | 590 Constructor superTarget; |
| 590 if (!isRedirectingGenerativeConstructor(constructor)) { | 591 builder.constructors.forEach((String name, Builder member) { |
| 592 if (member.isFactory) return; |
| 593 MemberBuilder constructorBuilder = member; |
| 594 Constructor constructor = constructorBuilder.target; |
| 595 if (!constructorBuilder.isRedirectingGenerativeConstructor) { |
| 591 /// >If no superinitializer is provided, an implicit superinitializer | 596 /// >If no superinitializer is provided, an implicit superinitializer |
| 592 /// >of the form super() is added at the end of k’s initializer list, | 597 /// >of the form super() is added at the end of k’s initializer list, |
| 593 /// >unless the enclosing class is class Object. | 598 /// >unless the enclosing class is class Object. |
| 594 if (!constructor.initializers.any(isSuperinitializerOrInvalid)) { | 599 if (constructor.initializers.isEmpty) { |
| 595 superTarget ??= defaultSuperConstructor(cls); | 600 superTarget ??= defaultSuperConstructor(cls); |
| 596 Initializer initializer; | 601 Initializer initializer; |
| 597 if (superTarget == null) { | 602 if (superTarget == null) { |
| 598 addError( | 603 addError( |
| 599 constructor.enclosingClass.fileUri, | 604 constructor.enclosingClass.fileUri, |
| 600 constructor.fileOffset, | 605 constructor.fileOffset, |
| 601 "${cls.superclass.name} has no constructor that takes no" | 606 "${cls.superclass.name} has no constructor that takes no" |
| 602 " arguments."); | 607 " arguments."); |
| 603 initializer = new InvalidInitializer(); | 608 initializer = new InvalidInitializer(); |
| 604 } else { | 609 } else { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 625 if (constructor.isConst && nonFinalFields.isNotEmpty) { | 630 if (constructor.isConst && nonFinalFields.isNotEmpty) { |
| 626 addError(constructor.enclosingClass.fileUri, constructor.fileOffset, | 631 addError(constructor.enclosingClass.fileUri, constructor.fileOffset, |
| 627 "Constructor is marked 'const' so all fields must be final."); | 632 "Constructor is marked 'const' so all fields must be final."); |
| 628 for (Field field in nonFinalFields) { | 633 for (Field field in nonFinalFields) { |
| 629 addError(constructor.enclosingClass.fileUri, field.fileOffset, | 634 addError(constructor.enclosingClass.fileUri, field.fileOffset, |
| 630 "Field isn't final, but constructor is 'const'."); | 635 "Field isn't final, but constructor is 'const'."); |
| 631 } | 636 } |
| 632 nonFinalFields.clear(); | 637 nonFinalFields.clear(); |
| 633 } | 638 } |
| 634 } | 639 } |
| 635 } | 640 }); |
| 636 Set<Field> initializedFields; | 641 Set<Field> initializedFields; |
| 637 fieldInitializers.forEach( | 642 fieldInitializers.forEach( |
| 638 (Constructor constructor, List<FieldInitializer> initializers) { | 643 (Constructor constructor, List<FieldInitializer> initializers) { |
| 639 Iterable<Field> fields = initializers.map((i) => i.field); | 644 Iterable<Field> fields = initializers.map((i) => i.field); |
| 640 if (initializedFields == null) { | 645 if (initializedFields == null) { |
| 641 initializedFields = new Set<Field>.from(fields); | 646 initializedFields = new Set<Field>.from(fields); |
| 642 } else { | 647 } else { |
| 643 initializedFields.addAll(fields); | 648 initializedFields.addAll(fields); |
| 644 } | 649 } |
| 645 }); | 650 }); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 print("$sb"); | 694 print("$sb"); |
| 690 ticker.logMs("Dumped IR"); | 695 ticker.logMs("Dumped IR"); |
| 691 } | 696 } |
| 692 | 697 |
| 693 void verify() { | 698 void verify() { |
| 694 errors.addAll(verifyProgram(program)); | 699 errors.addAll(verifyProgram(program)); |
| 695 ticker.logMs("Verified program"); | 700 ticker.logMs("Verified program"); |
| 696 } | 701 } |
| 697 } | 702 } |
| 698 | 703 |
| 699 bool isSuperinitializerOrInvalid(Initializer initializer) { | |
| 700 return initializer is SuperInitializer || initializer is InvalidInitializer; | |
| 701 } | |
| 702 | |
| 703 bool isRedirectingGenerativeConstructor(Constructor constructor) { | |
| 704 List<Initializer> initializers = constructor.initializers; | |
| 705 return initializers.length == 1 && | |
| 706 initializers.single is RedirectingInitializer; | |
| 707 } | |
| 708 | |
| 709 /// Looks for a constructor call that matches `super()` from a constructor in | 704 /// Looks for a constructor call that matches `super()` from a constructor in |
| 710 /// [cls]. Such a constructor may have optional arguments, but no required | 705 /// [cls]. Such a constructor may have optional arguments, but no required |
| 711 /// arguments. | 706 /// arguments. |
| 712 Constructor defaultSuperConstructor(Class cls) { | 707 Constructor defaultSuperConstructor(Class cls) { |
| 713 Class superclass = cls.superclass; | 708 Class superclass = cls.superclass; |
| 714 while (superclass != null && superclass.isMixinApplication) { | 709 while (superclass != null && superclass.isMixinApplication) { |
| 715 superclass = superclass.superclass; | 710 superclass = superclass.superclass; |
| 716 } | 711 } |
| 717 for (Constructor constructor in superclass.constructors) { | 712 for (Constructor constructor in superclass.constructors) { |
| 718 if (constructor.name.name.isEmpty) { | 713 if (constructor.name.name.isEmpty) { |
| 719 return constructor.function.requiredParameterCount == 0 | 714 return constructor.function.requiredParameterCount == 0 |
| 720 ? constructor | 715 ? constructor |
| 721 : null; | 716 : null; |
| 722 } | 717 } |
| 723 } | 718 } |
| 724 return null; | 719 return null; |
| 725 } | 720 } |
| OLD | NEW |