Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(399)

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 738863005: Respect order dependencies in ImplicitConstructorBuilder. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Sort unit/class members. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/non_error_resolver_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 engine.resolver; 5 library engine.resolver;
6 6
7 import "dart:math" as math; 7 import "dart:math" as math;
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:analyzer/src/generated/utilities_collection.dart';
11
10 import 'ast.dart'; 12 import 'ast.dart';
11 import 'constant.dart'; 13 import 'constant.dart';
12 import 'element.dart'; 14 import 'element.dart';
13 import 'element_resolver.dart'; 15 import 'element_resolver.dart';
14 import 'engine.dart'; 16 import 'engine.dart';
15 import 'error.dart'; 17 import 'error.dart';
16 import 'error_verifier.dart'; 18 import 'error_verifier.dart';
17 import 'html.dart' as ht; 19 import 'html.dart' as ht;
18 import 'instrumentation.dart'; 20 import 'instrumentation.dart';
19 import 'java_core.dart'; 21 import 'java_core.dart';
20 import 'java_engine.dart'; 22 import 'java_engine.dart';
21 import 'scanner.dart' as sc; 23 import 'scanner.dart' as sc;
22 import 'sdk.dart' show DartSdk, SdkLibrary; 24 import 'sdk.dart' show DartSdk, SdkLibrary;
23 import 'source.dart'; 25 import 'source.dart';
24 import 'static_type_analyzer.dart'; 26 import 'static_type_analyzer.dart';
25 import 'utilities_dart.dart'; 27 import 'utilities_dart.dart';
26 import 'utilities_general.dart'; 28 import 'utilities_general.dart';
27 29
28 /** 30 /**
31 * Callback signature used by ImplicitConstructorBuilder to register
32 * computations to be performed, and their dependencies. A call to this
33 * callback indicates that [computation] may be used to compute implicit
34 * constructors for [classElement], but that the computation may not be invoked
35 * until after implicit constructors have been built for [superclassElement].
36 */
37 typedef void ImplicitConstructorBuilderCallback(ClassElement classElement,
38 ClassElement superclassElement, void computation());
39
40 typedef void VoidFunction();
41
42 /**
29 * Instances of the class `AngularCompilationUnitBuilder` build an Angular speci fic element 43 * Instances of the class `AngularCompilationUnitBuilder` build an Angular speci fic element
30 * model for a single compilation unit. 44 * model for a single compilation unit.
31 */ 45 */
32 class AngularCompilationUnitBuilder { 46 class AngularCompilationUnitBuilder {
33 static String _NG_COMPONENT = "Component"; 47 static String _NG_COMPONENT = "Component";
34 48
35 static String _NG_CONTROLLER = "Controller"; 49 static String _NG_CONTROLLER = "Controller";
36 50
37 static String _NG_DECORATOR = "Decorator"; 51 static String _NG_DECORATOR = "Decorator";
38 52
(...skipping 5493 matching lines...) Expand 10 before | Expand all | Expand 10 after
5532 */ 5546 */
5533 void _reportValueError(ErrorCode errorCode, ht.XmlAttributeNode attribute, 5547 void _reportValueError(ErrorCode errorCode, ht.XmlAttributeNode attribute,
5534 List<Object> arguments) { 5548 List<Object> arguments) {
5535 int offset = attribute.valueToken.offset + 1; 5549 int offset = attribute.valueToken.offset + 1;
5536 int length = attribute.valueToken.length - 2; 5550 int length = attribute.valueToken.length - 2;
5537 _reportErrorForOffset(errorCode, offset, length, arguments); 5551 _reportErrorForOffset(errorCode, offset, length, arguments);
5538 } 5552 }
5539 } 5553 }
5540 5554
5541 /** 5555 /**
5542 * Instances of the class `SecondTypeResolverVisitor` are used to finish any res olve steps 5556 * Instances of the class `ImplicitConstructorBuilder` are used to build
5543 * after the [TypeResolverVisitor] that cannot happen in the [TypeResolverVisito r], but 5557 * implicit constructors for mixin applications, and to check for errors
5544 * should happen before the next tasks. 5558 * related to super constructor calls in class declarations with mixins.
5545 * 5559 *
5546 * Currently this visitor only finishes the resolution of [ClassTypeAlias]s, thu s the scopes 5560 * The visitor methods don't directly build the implicit constructors or check
5547 * of other top level AST nodes do not currently have to be built. 5561 * for errors, since they don't in general visit the classes in the proper
5562 * order to do so correctly. Instead, they pass closures to
5563 * ImplicitConstructorBuilderCallback to inform it of the computations to be
5564 * done and their ordering dependencies.
5548 */ 5565 */
5549 class ImplicitConstructorBuilder extends ScopedVisitor { 5566 class ImplicitConstructorBuilder extends ScopedVisitor {
5550 /** 5567 /**
5551 * Initialize a newly created visitor to finish resolution in the nodes in a c ompilation unit. 5568 * Callback to receive the computations to be performed.
5552 *
5553 * @param library the library containing the compilation unit being resolved
5554 * @param source the source representing the compilation unit being visited
5555 * @param typeProvider the object used to access the types from the core libra ry
5556 */ 5569 */
5557 ImplicitConstructorBuilder.con1(Library library, Source source, 5570 final ImplicitConstructorBuilderCallback _callback;
5558 TypeProvider typeProvider)
5559 : super.con1(library, source, typeProvider);
5560 5571
5561 /** 5572 /**
5562 * Initialize a newly created visitor to finish resolution in the nodes in a c ompilation unit. 5573 * Initialize a newly created visitor to build implicit constructors for file
5574 * [source], in library [libraryElement], which has scope [libraryScope]. Use
5575 * [typeProvider] to access types from the core library.
5563 * 5576 *
5564 * @param library the library containing the compilation unit being resolved 5577 * The visit methods will pass closures to [_callback] to indicate what
5565 * @param source the source representing the compilation unit being visited 5578 * computation needs to be performed, and its dependency order.
5566 * @param typeProvider the object used to access the types from the core libra ry
5567 */ 5579 */
5568 ImplicitConstructorBuilder.con2(ResolvableLibrary library, Source source, 5580 ImplicitConstructorBuilder(Source source, LibraryElement libraryElement,
5569 TypeProvider typeProvider) 5581 LibraryScope libraryScope, TypeProvider typeProvider, this._callback)
5570 : super.con4(library, source, typeProvider); 5582 : super.con3(
5583 libraryElement,
5584 source,
5585 typeProvider,
5586 libraryScope,
5587 libraryScope.errorListener);
5571 5588
5572 @override 5589 @override
5573 Object visitClassDeclaration(ClassDeclaration node) { 5590 Object visitClassDeclaration(ClassDeclaration node) {
5574 ClassElementImpl classElement = node.element; 5591 ClassElementImpl classElement = node.element;
5575 classElement.mixinErrorsReported = false; 5592 classElement.mixinErrorsReported = false;
5576 if (node.extendsClause != null && node.withClause != null) { 5593 if (node.extendsClause != null && node.withClause != null) {
5577 // We don't need to build any implicitly constructors for the mixin 5594 // We don't need to build any implicitly constructors for the mixin
5578 // application (since there isn't an explicit element for it), but we 5595 // application (since there isn't an explicit element for it), but we
5579 // need to verify that they _could_ be built. 5596 // need to verify that they _could_ be built.
5580 InterfaceType superclassType = null; 5597 InterfaceType superclassType = null;
5581 TypeName superclassName = node.extendsClause.superclass; 5598 TypeName superclassName = node.extendsClause.superclass;
5582 DartType type = superclassName.type; 5599 DartType type = superclassName.type;
5583 if (type is InterfaceType) { 5600 if (type is InterfaceType) {
5584 superclassType = type; 5601 superclassType = type;
5585 } else { 5602 } else {
5586 superclassType = typeProvider.objectType; 5603 superclassType = typeProvider.objectType;
5587 } 5604 }
5588 ClassElement superclassElement = classElement.supertype.element; 5605 ClassElement superclassElement = classElement.supertype.element;
5589 if (superclassElement != null) { 5606 if (superclassElement != null) {
5590 bool constructorFound = false; 5607 _callback(classElement, superclassElement, () {
5591 void callback(ConstructorElement explicitConstructor, 5608 bool constructorFound = false;
5592 List<DartType> parameterTypes, List<DartType> argumentTypes) { 5609 void callback(ConstructorElement explicitConstructor,
5593 constructorFound = true; 5610 List<DartType> parameterTypes, List<DartType> argumentTypes) {
5594 } 5611 constructorFound = true;
5595 if (_findForwardedConstructors( 5612 }
5596 classElement, 5613 if (_findForwardedConstructors(
5597 superclassName, 5614 classElement,
5598 superclassType, 5615 superclassName,
5599 callback) && 5616 superclassType,
5600 !constructorFound) { 5617 callback) &&
5601 reportErrorForNode( 5618 !constructorFound) {
5602 CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS, 5619 reportErrorForNode(
5603 node.withClause, 5620 CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
5604 [superclassType.element.name]); 5621 node.withClause,
5605 classElement.mixinErrorsReported = true; 5622 [superclassType.element.name]);
5606 } 5623 classElement.mixinErrorsReported = true;
5624 }
5625 });
5607 } 5626 }
5608 } 5627 }
5609 return null; 5628 return null;
5610 } 5629 }
5611 5630
5612 @override 5631 @override
5613 Object visitClassTypeAlias(ClassTypeAlias node) { 5632 Object visitClassTypeAlias(ClassTypeAlias node) {
5614 super.visitClassTypeAlias(node); 5633 super.visitClassTypeAlias(node);
5615 InterfaceType superclassType = null; 5634 InterfaceType superclassType = null;
5616 TypeName superclassName = node.superclass; 5635 TypeName superclassName = node.superclass;
5617 DartType type = superclassName.type; 5636 DartType type = superclassName.type;
5618 if (type is InterfaceType) { 5637 if (type is InterfaceType) {
5619 superclassType = type; 5638 superclassType = type;
5620 } else { 5639 } else {
5621 superclassType = typeProvider.objectType; 5640 superclassType = typeProvider.objectType;
5622 } 5641 }
5623 ClassElementImpl classElement = node.element as ClassElementImpl; 5642 ClassElementImpl classElement = node.element as ClassElementImpl;
5624 if (classElement != null) { 5643 if (classElement != null) {
5625 if (superclassType.element != null) { 5644 ClassElement superclassElement = superclassType.element;
5626 List<ConstructorElement> implicitConstructors = 5645 if (superclassElement != null) {
5627 new List<ConstructorElement>(); 5646 _callback(classElement, superclassElement, () {
5628 void callback(ConstructorElement explicitConstructor, 5647 List<ConstructorElement> implicitConstructors =
5629 List<DartType> parameterTypes, List<DartType> argumentTypes) { 5648 new List<ConstructorElement>();
5630 implicitConstructors.add( 5649 void callback(ConstructorElement explicitConstructor,
5631 _createImplicitContructor( 5650 List<DartType> parameterTypes, List<DartType> argumentTypes) {
5632 classElement.type, 5651 implicitConstructors.add(
5633 explicitConstructor, 5652 _createImplicitContructor(
5634 parameterTypes, 5653 classElement.type,
5635 argumentTypes)); 5654 explicitConstructor,
5636 } 5655 parameterTypes,
5637 if (_findForwardedConstructors( 5656 argumentTypes));
5638 classElement,
5639 superclassName,
5640 superclassType,
5641 callback)) {
5642 if (implicitConstructors.isEmpty) {
5643 reportErrorForNode(
5644 CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
5645 node,
5646 [superclassType.element.name]);
5647 } else {
5648 classElement.constructors = implicitConstructors;
5649 } 5657 }
5650 } 5658 if (_findForwardedConstructors(
5659 classElement,
5660 superclassName,
5661 superclassType,
5662 callback)) {
5663 if (implicitConstructors.isEmpty) {
5664 reportErrorForNode(
5665 CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
5666 node,
5667 [superclassElement.name]);
5668 } else {
5669 classElement.constructors = implicitConstructors;
5670 }
5671 }
5672 });
5651 } 5673 }
5652 } 5674 }
5653 return null; 5675 return null;
5654 } 5676 }
5655 5677
5656 @override 5678 @override
5657 Object visitEnumDeclaration(EnumDeclaration node) => null; 5679 Object visitEnumDeclaration(EnumDeclaration node) => null;
5658 5680
5659 @override 5681 @override
5660 Object visitFunctionDeclaration(FunctionDeclaration node) => null; 5682 Object visitFunctionDeclaration(FunctionDeclaration node) => null;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
5766 } 5788 }
5767 for (int i = argumentCount; i < parameterCount; i++) { 5789 for (int i = argumentCount; i < parameterCount; i++) {
5768 types[i] = dynamic; 5790 types[i] = dynamic;
5769 } 5791 }
5770 } 5792 }
5771 return types; 5793 return types;
5772 } 5794 }
5773 } 5795 }
5774 5796
5775 /** 5797 /**
5798 * An instance of this class is capable of running ImplicitConstructorBuilder
5799 * over all classes in a library cycle.
5800 */
5801 class ImplicitConstructorComputer {
5802 /**
5803 * The object used to access the types from the core library.
5804 */
5805 final TypeProvider typeProvider;
5806
5807 /**
5808 * Directed graph of dependencies between classes that need to have their
5809 * implicit constructors computed. Each edge in the graph points from a
5810 * derived class to its superclass. Implicit constructors will be computed
5811 * for the superclass before they are compute for the derived class.
5812 */
5813 DirectedGraph<ClassElement> _dependencies = new DirectedGraph<ClassElement>();
5814
5815 /**
5816 * Map from ClassElement to the function which will compute the class's
5817 * implicit constructors.
5818 */
5819 Map<ClassElement, VoidFunction> _computations =
5820 new HashMap<ClassElement, VoidFunction>();
5821
5822 /**
5823 * Create an ImplicitConstructorComputer which will use [typeProvider] to
5824 * access types from the core library.
5825 */
5826 ImplicitConstructorComputer(this.typeProvider);
5827
5828 /**
5829 * Add the given [unit] to the list of units which need to have implicit
5830 * constructors built for them. [source] is the source file corresponding to
5831 * the compilation unit, [libraryElement] is the library element containing
5832 * that source, and [libraryScope] is the scope for the library element.
5833 */
5834 void add(CompilationUnit unit, Source source, LibraryElement libraryElement,
5835 LibraryScope libraryScope) {
5836 unit.accept(
5837 new ImplicitConstructorBuilder(
5838 source,
5839 libraryElement,
5840 libraryScope,
5841 typeProvider,
5842 _defer));
5843 }
5844
5845 /**
5846 * Compute the implicit constructors for all compilation units that have been
5847 * passed to [add].
5848 */
5849 void compute() {
5850 List<List<ClassElement>> topologicalSort =
5851 _dependencies.computeTopologicalSort();
5852 for (List<ClassElement> classesInCycle in topologicalSort) {
5853 // Note: a cycle could occur if there is a loop in the inheritance graph.
5854 // Such loops are forbidden by Dart but could occur in the analysis of
5855 // incorrect code. If this happens, we simply visit the classes
5856 // constituting the loop in any order.
5857 for (ClassElement classElement in classesInCycle) {
5858 VoidFunction computation = _computations[classElement];
5859 if (computation != null) {
5860 computation();
5861 }
5862 }
5863 }
5864 }
5865
5866 /**
5867 * Defer execution of [computation], which builds implicit constructors for
5868 * [classElement], until after implicit constructors have been built for
5869 * [superclassElement].
5870 */
5871 void _defer(ClassElement classElement, ClassElement superclassElement, void
5872 computation()) {
5873 assert(!_computations.containsKey(classElement));
5874 _computations[classElement] = computation;
5875 _dependencies.addEdge(classElement, superclassElement);
5876 }
5877 }
5878
5879 /**
5776 * Instances of the class `ImplicitLabelScope` represent the scope statements 5880 * Instances of the class `ImplicitLabelScope` represent the scope statements
5777 * that can be the target of unlabeled break and continue statements. 5881 * that can be the target of unlabeled break and continue statements.
5778 */ 5882 */
5779 class ImplicitLabelScope { 5883 class ImplicitLabelScope {
5780 /** 5884 /**
5781 * The implicit label scope associated with the top level of a function. 5885 * The implicit label scope associated with the top level of a function.
5782 */ 5886 */
5783 static const ImplicitLabelScope ROOT = const ImplicitLabelScope._(null, null); 5887 static const ImplicitLabelScope ROOT = const ImplicitLabelScope._(null, null);
5784 5888
5785 /** 5889 /**
(...skipping 2944 matching lines...) Expand 10 before | Expand all | Expand 10 after
8730 /** 8834 /**
8731 * Finish steps that the [buildTypeHierarchies] could not perform, see 8835 * Finish steps that the [buildTypeHierarchies] could not perform, see
8732 * [ImplicitConstructorBuilder]. 8836 * [ImplicitConstructorBuilder].
8733 * 8837 *
8734 * @throws AnalysisException if any of the type hierarchies could not be resol ved 8838 * @throws AnalysisException if any of the type hierarchies could not be resol ved
8735 */ 8839 */
8736 void _buildImplicitConstructors() { 8840 void _buildImplicitConstructors() {
8737 TimeCounter_TimeCounterHandle timeCounter = 8841 TimeCounter_TimeCounterHandle timeCounter =
8738 PerformanceStatistics.resolve.start(); 8842 PerformanceStatistics.resolve.start();
8739 try { 8843 try {
8844 ImplicitConstructorComputer computer =
8845 new ImplicitConstructorComputer(_typeProvider);
8740 for (Library library in _librariesInCycles) { 8846 for (Library library in _librariesInCycles) {
8741 for (Source source in library.compilationUnitSources) { 8847 for (Source source in library.compilationUnitSources) {
8742 ImplicitConstructorBuilder visitor = 8848 computer.add(
8743 new ImplicitConstructorBuilder.con1(library, source, _typeProvider ); 8849 library.getAST(source),
8744 library.getAST(source).accept(visitor); 8850 source,
8851 library.libraryElement,
8852 library.libraryScope);
8745 } 8853 }
8746 } 8854 }
8855 computer.compute();
8747 } finally { 8856 } finally {
8748 timeCounter.stop(); 8857 timeCounter.stop();
8749 } 8858 }
8750 } 8859 }
8751 8860
8752 /** 8861 /**
8753 * Resolve the types referenced by function type aliases across all of the fun ction type aliases 8862 * Resolve the types referenced by function type aliases across all of the fun ction type aliases
8754 * defined in the current cycle. 8863 * defined in the current cycle.
8755 * 8864 *
8756 * @throws AnalysisException if any of the function type aliases could not be resolved 8865 * @throws AnalysisException if any of the function type aliases could not be resolved
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after
9470 /** 9579 /**
9471 * Finish steps that the [buildTypeHierarchies] could not perform, see 9580 * Finish steps that the [buildTypeHierarchies] could not perform, see
9472 * [ImplicitConstructorBuilder]. 9581 * [ImplicitConstructorBuilder].
9473 * 9582 *
9474 * @throws AnalysisException if any of the type hierarchies could not be resol ved 9583 * @throws AnalysisException if any of the type hierarchies could not be resol ved
9475 */ 9584 */
9476 void _buildImplicitConstructors() { 9585 void _buildImplicitConstructors() {
9477 TimeCounter_TimeCounterHandle timeCounter = 9586 TimeCounter_TimeCounterHandle timeCounter =
9478 PerformanceStatistics.resolve.start(); 9587 PerformanceStatistics.resolve.start();
9479 try { 9588 try {
9589 ImplicitConstructorComputer computer =
9590 new ImplicitConstructorComputer(_typeProvider);
9480 for (ResolvableLibrary library in _librariesInCycle) { 9591 for (ResolvableLibrary library in _librariesInCycle) {
9481 for (ResolvableCompilationUnit unit in 9592 for (ResolvableCompilationUnit unit in
9482 library.resolvableCompilationUnits) { 9593 library.resolvableCompilationUnits) {
9483 Source source = unit.source; 9594 Source source = unit.source;
9484 CompilationUnit ast = unit.compilationUnit; 9595 CompilationUnit ast = unit.compilationUnit;
9485 ImplicitConstructorBuilder visitor = 9596 computer.add(
9486 new ImplicitConstructorBuilder.con2(library, source, _typeProvider ); 9597 ast,
9487 ast.accept(visitor); 9598 source,
9599 library.libraryElement,
9600 library.libraryScope);
9488 } 9601 }
9489 } 9602 }
9603 computer.compute();
9490 } finally { 9604 } finally {
9491 timeCounter.stop(); 9605 timeCounter.stop();
9492 } 9606 }
9493 } 9607 }
9494 9608
9495 HashMap<Source, ResolvableLibrary> _buildLibraryMap() { 9609 HashMap<Source, ResolvableLibrary> _buildLibraryMap() {
9496 HashMap<Source, ResolvableLibrary> libraryMap = 9610 HashMap<Source, ResolvableLibrary> libraryMap =
9497 new HashMap<Source, ResolvableLibrary>(); 9611 new HashMap<Source, ResolvableLibrary>();
9498 int libraryCount = _librariesInCycle.length; 9612 int libraryCount = _librariesInCycle.length;
9499 for (int i = 0; i < libraryCount; i++) { 9613 for (int i = 0; i < libraryCount; i++) {
(...skipping 6786 matching lines...) Expand 10 before | Expand all | Expand 10 after
16286 * library. 16400 * library.
16287 */ 16401 */
16288 final HashSet<String> members = new HashSet<String>(); 16402 final HashSet<String> members = new HashSet<String>();
16289 16403
16290 /** 16404 /**
16291 * Names of resolved or unresolved class members that are read in the 16405 * Names of resolved or unresolved class members that are read in the
16292 * library. 16406 * library.
16293 */ 16407 */
16294 final HashSet<String> readMembers = new HashSet<String>(); 16408 final HashSet<String> readMembers = new HashSet<String>();
16295 } 16409 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/non_error_resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698