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

Side by Side Diff: lib/src/checker/checker.dart

Issue 1303913003: Fixes #287 and other failures statically checking SDK tests (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Cleanup Created 5 years, 4 months 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 | lib/src/checker/resolver.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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 dev_compiler.src.checker.checker; 5 library dev_compiler.src.checker.checker;
6 6
7 import 'package:analyzer/analyzer.dart'; 7 import 'package:analyzer/analyzer.dart';
8 import 'package:analyzer/src/generated/ast.dart'; 8 import 'package:analyzer/src/generated/ast.dart';
9 import 'package:analyzer/src/generated/element.dart'; 9 import 'package:analyzer/src/generated/element.dart';
10 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType; 10 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 /// } 76 /// }
77 /// class Parent extends Grandparent { 77 /// class Parent extends Grandparent {
78 /// m(A a) {} 78 /// m(A a) {}
79 /// } 79 /// }
80 /// class Test extends Parent { 80 /// class Test extends Parent {
81 /// m(B a) {} // invalid override 81 /// m(B a) {} // invalid override
82 /// } 82 /// }
83 void _checkSuperOverrides(ClassDeclaration node) { 83 void _checkSuperOverrides(ClassDeclaration node) {
84 var seen = new Set<String>(); 84 var seen = new Set<String>();
85 var current = node.element.type; 85 var current = node.element.type;
86 var visited = new Set<InterfaceType>();
86 do { 87 do {
88 visited.add(current);
87 current.mixins.reversed 89 current.mixins.reversed
88 .forEach((m) => _checkIndividualOverridesFromClass(node, m, seen)); 90 .forEach((m) => _checkIndividualOverridesFromClass(node, m, seen));
89 _checkIndividualOverridesFromClass(node, current.superclass, seen); 91 _checkIndividualOverridesFromClass(node, current.superclass, seen);
90 current = current.superclass; 92 current = current.superclass;
91 } while (!current.isObject); 93 } while (!current.isObject && !visited.contains(current));
92 } 94 }
93 95
94 /// Checks that implementations correctly override all reachable interfaces. 96 /// Checks that implementations correctly override all reachable interfaces.
95 /// In particular, we need to check these overrides for the definitions in 97 /// In particular, we need to check these overrides for the definitions in
96 /// the class itself and each its superclasses. If a superclass is not 98 /// the class itself and each its superclasses. If a superclass is not
97 /// abstract, then we can skip its transitive interfaces. For example, in: 99 /// abstract, then we can skip its transitive interfaces. For example, in:
98 /// 100 ///
99 /// B extends C implements G 101 /// B extends C implements G
100 /// A extends B with E, F implements H, I 102 /// A extends B with E, F implements H, I
101 /// 103 ///
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 /// Checks that [cls] and its super classes (including mixins) correctly 147 /// Checks that [cls] and its super classes (including mixins) correctly
146 /// overrides each interface in [interfaces]. If [includeParents] is false, 148 /// overrides each interface in [interfaces]. If [includeParents] is false,
147 /// then mixins are still checked, but the base type and it's transitive 149 /// then mixins are still checked, but the base type and it's transitive
148 /// supertypes are not. 150 /// supertypes are not.
149 /// 151 ///
150 /// [cls] can be either a [ClassDeclaration] or a [InterfaceType]. For 152 /// [cls] can be either a [ClassDeclaration] or a [InterfaceType]. For
151 /// [ClassDeclaration]s errors are reported on the member that contains the 153 /// [ClassDeclaration]s errors are reported on the member that contains the
152 /// invalid override, for [InterfaceType]s we use [errorLocation] instead. 154 /// invalid override, for [InterfaceType]s we use [errorLocation] instead.
153 void _checkInterfacesOverrides( 155 void _checkInterfacesOverrides(
154 cls, Iterable<InterfaceType> interfaces, Set<String> seen, 156 cls, Iterable<InterfaceType> interfaces, Set<String> seen,
155 {bool includeParents: true, AstNode errorLocation}) { 157 {Set<InterfaceType> visited,
158 bool includeParents: true,
159 AstNode errorLocation}) {
156 var node = cls is ClassDeclaration ? cls : null; 160 var node = cls is ClassDeclaration ? cls : null;
157 var type = cls is InterfaceType ? cls : node.element.type; 161 var type = cls is InterfaceType ? cls : node.element.type;
158 162
163 if (visited == null) {
164 visited = new Set<InterfaceType>();
165 } else if (visited.contains(type)) {
166 // Malformed type.
167 return;
168 } else {
169 visited.add(type);
170 }
171
159 // Check direct overrides on [type] 172 // Check direct overrides on [type]
160 for (var interfaceType in interfaces) { 173 for (var interfaceType in interfaces) {
161 if (node != null) { 174 if (node != null) {
162 _checkIndividualOverridesFromClass(node, interfaceType, seen); 175 _checkIndividualOverridesFromClass(node, interfaceType, seen);
163 } else { 176 } else {
164 _checkIndividualOverridesFromType( 177 _checkIndividualOverridesFromType(
165 type, interfaceType, errorLocation, seen); 178 type, interfaceType, errorLocation, seen);
166 } 179 }
167 } 180 }
168 181
(...skipping 10 matching lines...) Expand all
179 } 192 }
180 193
181 // Check overrides from its superclasses 194 // Check overrides from its superclasses
182 if (includeParents) { 195 if (includeParents) {
183 var parent = type.superclass; 196 var parent = type.superclass;
184 if (parent.isObject) return; 197 if (parent.isObject) return;
185 var loc = errorLocation != null ? errorLocation : node.extendsClause; 198 var loc = errorLocation != null ? errorLocation : node.extendsClause;
186 // No need to copy [seen] here because we made copies above when reporting 199 // No need to copy [seen] here because we made copies above when reporting
187 // errors on mixins. 200 // errors on mixins.
188 _checkInterfacesOverrides(parent, interfaces, seen, 201 _checkInterfacesOverrides(parent, interfaces, seen,
189 includeParents: true, errorLocation: loc); 202 visited: visited, includeParents: true, errorLocation: loc);
190 } 203 }
191 } 204 }
192 205
193 /// Check that individual methods and fields in [subType] correctly override 206 /// Check that individual methods and fields in [subType] correctly override
194 /// the declarations in [baseType]. 207 /// the declarations in [baseType].
195 /// 208 ///
196 /// The [errorLocation] node indicates where errors are reported, see 209 /// The [errorLocation] node indicates where errors are reported, see
197 /// [_checkSingleOverride] for more details. 210 /// [_checkSingleOverride] for more details.
198 /// 211 ///
199 /// The set [seen] is used to avoid reporting overrides more than once. It 212 /// The set [seen] is used to avoid reporting overrides more than once. It
(...skipping 25 matching lines...) Expand all
225 if (member is FieldDeclaration) { 238 if (member is FieldDeclaration) {
226 if (member.isStatic) continue; 239 if (member.isStatic) continue;
227 for (var variable in member.fields.variables) { 240 for (var variable in member.fields.variables) {
228 var element = variable.element as PropertyInducingElement; 241 var element = variable.element as PropertyInducingElement;
229 var name = element.name; 242 var name = element.name;
230 if (seen.contains(name)) continue; 243 if (seen.contains(name)) continue;
231 var getter = element.getter; 244 var getter = element.getter;
232 var setter = element.setter; 245 var setter = element.setter;
233 bool found = _checkSingleOverride(getter, baseType, variable, member); 246 bool found = _checkSingleOverride(getter, baseType, variable, member);
234 if (!variable.isFinal && 247 if (!variable.isFinal &&
248 !variable.isConst &&
235 _checkSingleOverride(setter, baseType, variable, member)) { 249 _checkSingleOverride(setter, baseType, variable, member)) {
236 found = true; 250 found = true;
237 } 251 }
238 if (found) seen.add(name); 252 if (found) seen.add(name);
239 } 253 }
240 } else { 254 } else {
241 if ((member as MethodDeclaration).isStatic) continue; 255 if ((member as MethodDeclaration).isStatic) continue;
242 var method = (member as MethodDeclaration).element; 256 var method = (member as MethodDeclaration).element;
243 if (seen.contains(method.name)) continue; 257 if (seen.contains(method.name)) continue;
244 if (_checkSingleOverride(method, baseType, member, member)) { 258 if (_checkSingleOverride(method, baseType, member, member)) {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 396
383 @override 397 @override
384 void visitForEachStatement(ForEachStatement node) { 398 void visitForEachStatement(ForEachStatement node) {
385 // Check that the expression is an Iterable. 399 // Check that the expression is an Iterable.
386 var expr = node.iterable; 400 var expr = node.iterable;
387 var iterableType = node.awaitKeyword != null 401 var iterableType = node.awaitKeyword != null
388 ? rules.provider.streamType 402 ? rules.provider.streamType
389 : rules.provider.iterableType; 403 : rules.provider.iterableType;
390 var loopVariable = node.identifier != null 404 var loopVariable = node.identifier != null
391 ? node.identifier 405 ? node.identifier
392 : node.loopVariable.identifier; 406 : node.loopVariable?.identifier;
393 var iteratorType = loopVariable.staticType; 407 if (loopVariable != null) {
394 var checkedType = iterableType.substitute4([iteratorType]); 408 var iteratorType = loopVariable.staticType;
395 checkAssignment(expr, checkedType); 409 var checkedType = iterableType.substitute4([iteratorType]);
410 checkAssignment(expr, checkedType);
411 }
396 node.visitChildren(this); 412 node.visitChildren(this);
397 } 413 }
398 414
399 @override 415 @override
400 void visitForStatement(ForStatement node) { 416 void visitForStatement(ForStatement node) {
401 if (node.condition != null) { 417 if (node.condition != null) {
402 checkBoolean(node.condition); 418 checkBoolean(node.condition);
403 } 419 }
404 node.visitChildren(this); 420 node.visitChildren(this);
405 } 421 }
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 if (info is CoercionInfo) { 934 if (info is CoercionInfo) {
919 // TODO(jmesserly): if we're run again on the same AST, we'll produce the 935 // TODO(jmesserly): if we're run again on the same AST, we'll produce the
920 // same annotations. This should be harmless. This might go away once 936 // same annotations. This should be harmless. This might go away once
921 // CodeChecker is integrated better with analyzer, as it will know that 937 // CodeChecker is integrated better with analyzer, as it will know that
922 // checking has already been performed. 938 // checking has already been performed.
923 // assert(CoercionInfo.get(info.node) == null); 939 // assert(CoercionInfo.get(info.node) == null);
924 CoercionInfo.set(info.node, info); 940 CoercionInfo.set(info.node, info);
925 } 941 }
926 } 942 }
927 } 943 }
OLDNEW
« no previous file with comments | « no previous file | lib/src/checker/resolver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698