OLD | NEW |
---|---|
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:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/src/generated/scanner.dart'; | 9 import 'package:analyzer/src/generated/scanner.dart'; |
10 | 10 |
(...skipping 10903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10914 // | 10914 // |
10915 // Continue the class resolution. | 10915 // Continue the class resolution. |
10916 // | 10916 // |
10917 enclosingClass = node.element; | 10917 enclosingClass = node.element; |
10918 typeAnalyzer.thisType = enclosingClass == null ? null : enclosingClass.type; | 10918 typeAnalyzer.thisType = enclosingClass == null ? null : enclosingClass.type; |
10919 node.accept(elementResolver); | 10919 node.accept(elementResolver); |
10920 node.accept(typeAnalyzer); | 10920 node.accept(typeAnalyzer); |
10921 } | 10921 } |
10922 | 10922 |
10923 @override | 10923 @override |
10924 void visitClassMembersInScope(ClassDeclaration node) { | |
10925 safelyVisit(node.documentationComment); | |
10926 node.metadata.accept(this); | |
10927 // | |
10928 // Visit the fields before other members so that instance fields will have | |
10929 // propagated types associated with them before we see their use sites. | |
10930 // | |
10931 List<ClassMember> nonFields = <ClassMember>[]; | |
10932 for (ClassMember member in node.members) { | |
10933 if (member is FieldDeclaration) { | |
10934 member.accept(this); | |
10935 } else { | |
10936 nonFields.add(member); | |
10937 } | |
10938 } | |
10939 for (ClassMember member in nonFields) { | |
10940 member.accept(this); | |
10941 } | |
10942 } | |
10943 | |
10944 @override | |
10924 Object visitComment(Comment node) { | 10945 Object visitComment(Comment node) { |
10925 if (node.parent is FunctionDeclaration || | 10946 if (node.parent is FunctionDeclaration || |
10926 node.parent is ConstructorDeclaration || | 10947 node.parent is ConstructorDeclaration || |
10927 node.parent is MethodDeclaration) { | 10948 node.parent is MethodDeclaration) { |
10928 if (!identical(node, _commentBeforeFunction)) { | 10949 if (!identical(node, _commentBeforeFunction)) { |
10929 _commentBeforeFunction = node; | 10950 _commentBeforeFunction = node; |
10930 return null; | 10951 return null; |
10931 } | 10952 } |
10932 } | 10953 } |
10933 super.visitComment(node); | 10954 super.visitComment(node); |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11525 return null; | 11546 return null; |
11526 } | 11547 } |
11527 | 11548 |
11528 @override | 11549 @override |
11529 Object visitTypeName(TypeName node) => null; | 11550 Object visitTypeName(TypeName node) => null; |
11530 | 11551 |
11531 @override | 11552 @override |
11532 Object visitVariableDeclaration(VariableDeclaration node) { | 11553 Object visitVariableDeclaration(VariableDeclaration node) { |
11533 super.visitVariableDeclaration(node); | 11554 super.visitVariableDeclaration(node); |
11534 VariableElement element = node.element; | 11555 VariableElement element = node.element; |
11535 if (element.initializer != null && node.initializer != null) { | 11556 FunctionElement initializerElement = element.initializer; |
11536 (element.initializer as FunctionElementImpl).returnType = | 11557 Expression initializer = node.initializer; |
11537 node.initializer.staticType; | 11558 if (initializerElement is FunctionElementImpl && initializer != null) { |
11559 initializerElement.returnType = initializer.staticType; | |
11560 } | |
11561 // | |
11562 // Propagate types for instance fields. Top-level variables and static | |
11563 // fields are handled elsewhere. | |
11564 // | |
11565 if (initializer != null && | |
11566 element is FieldElementImpl && | |
11567 !element.isStatic && | |
11568 (element.isFinal || element.isConst)) { | |
Paul Berry
2015/10/29 17:49:17
Isn't the test for `element.isConst` redundant? I
Brian Wilkerson
2015/10/29 18:31:04
Actually, no. With illegal code, such as "const in
| |
11569 DartType staticType = element.type; | |
11570 DartType bestType = initializer.bestType; | |
11571 if (bestType != null && | |
11572 bestType != staticType && | |
11573 bestType.isMoreSpecificThan(staticType)) { | |
11574 element.propagatedType = bestType; | |
11575 } | |
11538 } | 11576 } |
11539 // Note: in addition to cloning the initializers for const variables, we | 11577 // Note: in addition to cloning the initializers for const variables, we |
11540 // have to clone the initializers for non-static final fields (because if | 11578 // have to clone the initializers for non-static final fields (because if |
11541 // they occur in a class with a const constructor, they will be needed to | 11579 // they occur in a class with a const constructor, they will be needed to |
11542 // evaluate the const constructor). | 11580 // evaluate the const constructor). |
11543 if ((element.isConst || | 11581 if ((element.isConst || |
11544 (element is FieldElement && | 11582 (element is FieldElement && |
11545 element.isFinal && | 11583 element.isFinal && |
11546 !element.isStatic)) && | 11584 !element.isStatic)) && |
11547 node.initializer != null) { | 11585 initializer != null) { |
11548 (element as ConstVariableElement).constantInitializer = | 11586 (element as ConstVariableElement).constantInitializer = |
11549 new ConstantAstCloner().cloneNode(node.initializer); | 11587 new ConstantAstCloner().cloneNode(initializer); |
11550 } | 11588 } |
11551 return null; | 11589 return null; |
11552 } | 11590 } |
11553 | 11591 |
11554 @override | 11592 @override |
11555 Object visitWhileStatement(WhileStatement node) { | 11593 Object visitWhileStatement(WhileStatement node) { |
11556 // Note: since we don't call the base class, we have to maintain | 11594 // Note: since we don't call the base class, we have to maintain |
11557 // _implicitLabelScope ourselves. | 11595 // _implicitLabelScope ourselves. |
11558 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; | 11596 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; |
11559 try { | 11597 try { |
(...skipping 4535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16095 nonFields.add(node); | 16133 nonFields.add(node); |
16096 return null; | 16134 return null; |
16097 } | 16135 } |
16098 | 16136 |
16099 @override | 16137 @override |
16100 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 16138 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
16101 | 16139 |
16102 @override | 16140 @override |
16103 Object visitWithClause(WithClause node) => null; | 16141 Object visitWithClause(WithClause node) => null; |
16104 } | 16142 } |
OLD | NEW |