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

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

Issue 1410493006: Compute propagated type for final instance fields (partially addresses issue 23001) (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/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: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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698