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

Side by Side Diff: packages/analyzer/lib/src/generated/error_verifier.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 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
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.error_verifier; 5 library analyzer.src.generated.error_verifier;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import "dart:math" as math; 8 import "dart:math" as math;
9 9
10 import 'package:analyzer/src/generated/static_type_analyzer.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
11 11 import 'package:analyzer/dart/ast/token.dart';
12 import 'ast.dart'; 12 import 'package:analyzer/dart/ast/visitor.dart';
13 import 'constant.dart'; 13 import 'package:analyzer/dart/element/element.dart';
14 import 'element.dart'; 14 import 'package:analyzer/dart/element/type.dart';
15 import 'element_resolver.dart'; 15 import 'package:analyzer/dart/element/visitor.dart';
16 import 'error.dart'; 16 import 'package:analyzer/error/error.dart';
17 import 'java_engine.dart'; 17 import 'package:analyzer/error/listener.dart';
18 import 'parser.dart' show Parser, ParserErrorCode; 18 import 'package:analyzer/src/dart/element/element.dart';
19 import 'resolver.dart'; 19 import 'package:analyzer/src/dart/element/member.dart';
20 import 'scanner.dart' as sc; 20 import 'package:analyzer/src/dart/element/type.dart';
21 import 'sdk.dart' show DartSdk, SdkLibrary; 21 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
22 import 'utilities_dart.dart'; 22 import 'package:analyzer/src/error/codes.dart';
23 import 'package:analyzer/src/error/pending_error.dart';
24 import 'package:analyzer/src/generated/constant.dart';
25 import 'package:analyzer/src/generated/element_resolver.dart';
26 import 'package:analyzer/src/generated/engine.dart';
27 import 'package:analyzer/src/generated/java_engine.dart';
28 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
29 import 'package:analyzer/src/generated/resolver.dart';
30 import 'package:analyzer/src/generated/sdk.dart' show DartSdk, SdkLibrary;
31 import 'package:analyzer/src/generated/source.dart';
32 import 'package:analyzer/src/generated/utilities_dart.dart';
33 import 'package:analyzer/src/task/dart.dart';
34 import 'package:analyzer/src/task/strong/checker.dart' as checker
35 show isKnownFunction;
23 36
24 /** 37 /**
25 * A visitor used to traverse an AST structure looking for additional errors and 38 * A visitor used to traverse an AST structure looking for additional errors and
26 * warnings not covered by the parser and resolver. 39 * warnings not covered by the parser and resolver.
27 */ 40 */
28 class ErrorVerifier extends RecursiveAstVisitor<Object> { 41 class ErrorVerifier extends RecursiveAstVisitor<Object> {
29 /** 42 /**
30 * Static final string with value `"getter "` used in the construction of the 43 * Static final string with value `"getter "` used in the construction of the
31 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and 44 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and
32 * similar, error code messages. 45 * similar, error code messages.
(...skipping 25 matching lines...) Expand all
58 * The type representing the type 'bool'. 71 * The type representing the type 'bool'.
59 */ 72 */
60 InterfaceType _boolType; 73 InterfaceType _boolType;
61 74
62 /** 75 /**
63 * The type representing the type 'int'. 76 * The type representing the type 'int'.
64 */ 77 */
65 InterfaceType _intType; 78 InterfaceType _intType;
66 79
67 /** 80 /**
81 * The options for verification.
82 */
83 AnalysisOptionsImpl _options;
84
85 /**
68 * The object providing access to the types defined by the language. 86 * The object providing access to the types defined by the language.
69 */ 87 */
70 final TypeProvider _typeProvider; 88 final TypeProvider _typeProvider;
71 89
72 /** 90 /**
73 * The type system primitives 91 * The type system primitives
74 */ 92 */
75 TypeSystem _typeSystem; 93 TypeSystem _typeSystem;
76 94
77 /** 95 /**
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 * [StaticWarningCode.MIXED_RETURN_TYPES] and 203 * [StaticWarningCode.MIXED_RETURN_TYPES] and
186 * [StaticWarningCode.RETURN_WITHOUT_VALUE] from being generated in the same 204 * [StaticWarningCode.RETURN_WITHOUT_VALUE] from being generated in the same
187 * function body. 205 * function body.
188 */ 206 */
189 bool _hasReturnWithoutValue = false; 207 bool _hasReturnWithoutValue = false;
190 208
191 /** 209 /**
192 * The class containing the AST nodes being visited, or `null` if we are not 210 * The class containing the AST nodes being visited, or `null` if we are not
193 * in the scope of a class. 211 * in the scope of a class.
194 */ 212 */
195 ClassElement _enclosingClass; 213 ClassElementImpl _enclosingClass;
214
215 /**
216 * The enum containing the AST nodes being visited, or `null` if we are not
217 * in the scope of an enum.
218 */
219 ClassElement _enclosingEnum;
196 220
197 /** 221 /**
198 * The method or function that we are currently visiting, or `null` if we are 222 * The method or function that we are currently visiting, or `null` if we are
199 * not inside a method or function. 223 * not inside a method or function.
200 */ 224 */
201 ExecutableElement _enclosingFunction; 225 ExecutableElement _enclosingFunction;
202 226
203 /** 227 /**
204 * The return statements found in the method or function that we are currently 228 * The return statements found in the method or function that we are currently
205 * visiting that have a return value. 229 * visiting that have a return value.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 */ 271 */
248 HashMap<String, Element> _exportedElements = new HashMap<String, Element>(); 272 HashMap<String, Element> _exportedElements = new HashMap<String, Element>();
249 273
250 /** 274 /**
251 * A set of the names of the variable initializers we are visiting now. 275 * A set of the names of the variable initializers we are visiting now.
252 */ 276 */
253 HashSet<String> _namesForReferenceToDeclaredVariableInInitializer = 277 HashSet<String> _namesForReferenceToDeclaredVariableInInitializer =
254 new HashSet<String>(); 278 new HashSet<String>();
255 279
256 /** 280 /**
281 * The elements that will be defined later in the current scope, but right
282 * now are not declared.
283 */
284 HiddenElements _hiddenElements = null;
285
286 /**
257 * A list of types used by the [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS] 287 * A list of types used by the [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]
258 * and [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS] error codes. 288 * and [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS] error codes.
259 */ 289 */
260 List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT; 290 List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT;
261 291
262 /** 292 /**
263 * If `true`, mixins are allowed to inherit from types other than Object, and 293 * If `true`, mixins are allowed to inherit from types other than Object, and
264 * are allowed to reference `super`. 294 * are allowed to reference `super`.
265 */ 295 */
266 final bool enableSuperMixins; 296 final bool enableSuperMixins;
267 297
268 /** 298 /**
299 * If `true`, asserts are allowed to take a second argument representing the
300 * assertion failure message (see DEP 37).
301 */
302 final bool enableAssertMessage;
303
304 /**
269 * Initialize a newly created error verifier. 305 * Initialize a newly created error verifier.
270 */ 306 */
271 ErrorVerifier(this._errorReporter, this._currentLibrary, this._typeProvider, 307 ErrorVerifier(
272 this._inheritanceManager, this.enableSuperMixins) { 308 this._errorReporter,
309 this._currentLibrary,
310 this._typeProvider,
311 this._inheritanceManager,
312 this.enableSuperMixins,
313 this.enableAssertMessage) {
273 this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary; 314 this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
274 this._hasExtUri = _currentLibrary.hasExtUri; 315 this._hasExtUri = _currentLibrary.hasExtUri;
275 _isEnclosingConstructorConst = false; 316 _isEnclosingConstructorConst = false;
276 _isInCatchClause = false; 317 _isInCatchClause = false;
277 _isInStaticVariableDeclaration = false; 318 _isInStaticVariableDeclaration = false;
278 _isInInstanceVariableDeclaration = false; 319 _isInInstanceVariableDeclaration = false;
279 _isInInstanceVariableInitializer = false; 320 _isInInstanceVariableInitializer = false;
280 _isInConstructorInitializer = false; 321 _isInConstructorInitializer = false;
281 _isInStaticMethod = false; 322 _isInStaticMethod = false;
282 _boolType = _typeProvider.boolType; 323 _boolType = _typeProvider.boolType;
283 _intType = _typeProvider.intType; 324 _intType = _typeProvider.intType;
284 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = _typeProvider.nonSubtypableTypes; 325 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = _typeProvider.nonSubtypableTypes;
285 _typeSystem = _currentLibrary.context.typeSystem; 326 _typeSystem = _currentLibrary.context.typeSystem;
327 _options = _currentLibrary.context.analysisOptions;
286 } 328 }
287 329
288 @override 330 @override
289 Object visitAnnotation(Annotation node) { 331 Object visitAnnotation(Annotation node) {
290 _checkForInvalidAnnotationFromDeferredLibrary(node); 332 _checkForInvalidAnnotationFromDeferredLibrary(node);
333 _checkForMissingJSLibAnnotation(node);
291 return super.visitAnnotation(node); 334 return super.visitAnnotation(node);
292 } 335 }
293 336
294 @override 337 @override
295 Object visitArgumentList(ArgumentList node) { 338 Object visitArgumentList(ArgumentList node) {
296 _checkForArgumentTypesNotAssignableInList(node); 339 _checkForArgumentTypesNotAssignableInList(node);
297 return super.visitArgumentList(node); 340 return super.visitArgumentList(node);
298 } 341 }
299 342
300 @override 343 @override
301 Object visitAsExpression(AsExpression node) { 344 Object visitAsExpression(AsExpression node) {
302 _checkForTypeAnnotationDeferredClass(node.type); 345 _checkForTypeAnnotationDeferredClass(node.type);
303 return super.visitAsExpression(node); 346 return super.visitAsExpression(node);
304 } 347 }
305 348
306 @override 349 @override
307 Object visitAssertStatement(AssertStatement node) { 350 Object visitAssertStatement(AssertStatement node) {
308 _checkForNonBoolExpression(node); 351 _checkForNonBoolExpression(node);
352 _checkAssertMessage(node);
309 return super.visitAssertStatement(node); 353 return super.visitAssertStatement(node);
310 } 354 }
311 355
312 @override 356 @override
313 Object visitAssignmentExpression(AssignmentExpression node) { 357 Object visitAssignmentExpression(AssignmentExpression node) {
314 sc.TokenType operatorType = node.operator.type; 358 TokenType operatorType = node.operator.type;
315 Expression lhs = node.leftHandSide; 359 Expression lhs = node.leftHandSide;
316 Expression rhs = node.rightHandSide; 360 Expression rhs = node.rightHandSide;
317 if (operatorType == sc.TokenType.EQ || 361 if (operatorType == TokenType.EQ ||
318 operatorType == sc.TokenType.QUESTION_QUESTION_EQ) { 362 operatorType == TokenType.QUESTION_QUESTION_EQ) {
319 _checkForInvalidAssignment(lhs, rhs); 363 _checkForInvalidAssignment(lhs, rhs);
320 } else { 364 } else {
321 _checkForInvalidCompoundAssignment(node, lhs, rhs); 365 _checkForInvalidCompoundAssignment(node, lhs, rhs);
322 _checkForArgumentTypeNotAssignableForArgument(rhs); 366 _checkForArgumentTypeNotAssignableForArgument(rhs);
323 } 367 }
324 _checkForAssignmentToFinal(lhs); 368 _checkForAssignmentToFinal(lhs);
325 return super.visitAssignmentExpression(node); 369 return super.visitAssignmentExpression(node);
326 } 370 }
327 371
328 @override 372 @override
329 Object visitAwaitExpression(AwaitExpression node) { 373 Object visitAwaitExpression(AwaitExpression node) {
330 if (!_inAsync) { 374 if (!_inAsync) {
331 _errorReporter.reportErrorForToken( 375 _errorReporter.reportErrorForToken(
332 CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, node.awaitKeyword); 376 CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, node.awaitKeyword);
333 } 377 }
334 return super.visitAwaitExpression(node); 378 return super.visitAwaitExpression(node);
335 } 379 }
336 380
337 @override 381 @override
338 Object visitBinaryExpression(BinaryExpression node) { 382 Object visitBinaryExpression(BinaryExpression node) {
339 sc.Token operator = node.operator; 383 Token operator = node.operator;
340 sc.TokenType type = operator.type; 384 TokenType type = operator.type;
341 if (type == sc.TokenType.AMPERSAND_AMPERSAND || 385 if (type == TokenType.AMPERSAND_AMPERSAND || type == TokenType.BAR_BAR) {
342 type == sc.TokenType.BAR_BAR) {
343 String lexeme = operator.lexeme; 386 String lexeme = operator.lexeme;
344 _checkForAssignability(node.leftOperand, _boolType, 387 _checkForAssignability(node.leftOperand, _boolType,
345 StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]); 388 StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]);
346 _checkForAssignability(node.rightOperand, _boolType, 389 _checkForAssignability(node.rightOperand, _boolType,
347 StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]); 390 StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]);
348 } else { 391 } else {
349 _checkForArgumentTypeNotAssignableForArgument(node.rightOperand); 392 _checkForArgumentTypeNotAssignableForArgument(node.rightOperand);
350 } 393 }
351 return super.visitBinaryExpression(node); 394 return super.visitBinaryExpression(node);
352 } 395 }
353 396
354 @override 397 @override
398 Object visitBlock(Block node) {
399 _hiddenElements = new HiddenElements(_hiddenElements, node);
400 try {
401 _checkDuplicateDeclarationInStatements(node.statements);
402 return super.visitBlock(node);
403 } finally {
404 _hiddenElements = _hiddenElements.outerElements;
405 }
406 }
407
408 @override
355 Object visitBlockFunctionBody(BlockFunctionBody node) { 409 Object visitBlockFunctionBody(BlockFunctionBody node) {
356 bool wasInAsync = _inAsync; 410 bool wasInAsync = _inAsync;
357 bool wasInGenerator = _inGenerator; 411 bool wasInGenerator = _inGenerator;
358 bool previousHasReturnWithoutValue = _hasReturnWithoutValue; 412 bool previousHasReturnWithoutValue = _hasReturnWithoutValue;
359 _hasReturnWithoutValue = false; 413 _hasReturnWithoutValue = false;
360 List<ReturnStatement> previousReturnsWith = _returnsWith; 414 List<ReturnStatement> previousReturnsWith = _returnsWith;
361 List<ReturnStatement> previousReturnsWithout = _returnsWithout; 415 List<ReturnStatement> previousReturnsWithout = _returnsWithout;
362 try { 416 try {
363 _inAsync = node.isAsynchronous; 417 _inAsync = node.isAsynchronous;
364 _inGenerator = node.isGenerator; 418 _inGenerator = node.isGenerator;
(...skipping 19 matching lines...) Expand all
384 if (labelElement is LabelElementImpl && labelElement.isOnSwitchMember) { 438 if (labelElement is LabelElementImpl && labelElement.isOnSwitchMember) {
385 _errorReporter.reportErrorForNode( 439 _errorReporter.reportErrorForNode(
386 ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode); 440 ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode);
387 } 441 }
388 } 442 }
389 return null; 443 return null;
390 } 444 }
391 445
392 @override 446 @override
393 Object visitCatchClause(CatchClause node) { 447 Object visitCatchClause(CatchClause node) {
448 _checkDuplicateDefinitionInCatchClause(node);
394 bool previousIsInCatchClause = _isInCatchClause; 449 bool previousIsInCatchClause = _isInCatchClause;
395 try { 450 try {
396 _isInCatchClause = true; 451 _isInCatchClause = true;
397 _checkForTypeAnnotationDeferredClass(node.exceptionType); 452 _checkForTypeAnnotationDeferredClass(node.exceptionType);
398 return super.visitCatchClause(node); 453 return super.visitCatchClause(node);
399 } finally { 454 } finally {
400 _isInCatchClause = previousIsInCatchClause; 455 _isInCatchClause = previousIsInCatchClause;
401 } 456 }
402 } 457 }
403 458
404 @override 459 @override
405 Object visitClassDeclaration(ClassDeclaration node) { 460 Object visitClassDeclaration(ClassDeclaration node) {
406 ClassElement outerClass = _enclosingClass; 461 ClassElementImpl outerClass = _enclosingClass;
407 try { 462 try {
408 _isInNativeClass = node.nativeClause != null; 463 _isInNativeClass = node.nativeClause != null;
409 _enclosingClass = node.element; 464 _enclosingClass = AbstractClassElementImpl.getImpl(node.element);
410 ExtendsClause extendsClause = node.extendsClause; 465 _checkDuplicateClassMembers(node);
411 ImplementsClause implementsClause = node.implementsClause;
412 WithClause withClause = node.withClause;
413 _checkForBuiltInIdentifierAsName( 466 _checkForBuiltInIdentifierAsName(
414 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME); 467 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
415 _checkForMemberWithClassName(); 468 _checkForMemberWithClassName();
416 _checkForNoDefaultSuperConstructorImplicit(node); 469 _checkForNoDefaultSuperConstructorImplicit(node);
417 _checkForConflictingTypeVariableErrorCodes(node); 470 _checkForConflictingTypeVariableErrorCodes(node);
471 ExtendsClause extendsClause = node.extendsClause;
472 ImplementsClause implementsClause = node.implementsClause;
473 WithClause withClause = node.withClause;
418 // Only do error checks on the clause nodes if there is a non-null clause 474 // Only do error checks on the clause nodes if there is a non-null clause
419 if (implementsClause != null || 475 if (implementsClause != null ||
420 extendsClause != null || 476 extendsClause != null ||
421 withClause != null) { 477 withClause != null) {
422 // Only check for all of the inheritance logic around clauses if there 478 // Only check for all of the inheritance logic around clauses if there
423 // isn't an error code such as "Cannot extend double" already on the 479 // isn't an error code such as "Cannot extend double" already on the
424 // class. 480 // class.
425 if (!_checkForImplementsDisallowedClass(implementsClause) && 481 if (!_checkForImplementsDisallowedClass(implementsClause) &&
426 !_checkForExtendsDisallowedClass(extendsClause) && 482 !_checkForExtendsDisallowedClass(extendsClause) &&
427 !_checkForAllMixinErrorCodes(withClause)) { 483 !_checkForAllMixinErrorCodes(withClause)) {
(...skipping 20 matching lines...) Expand all
448 _enclosingClass = outerClass; 504 _enclosingClass = outerClass;
449 } 505 }
450 } 506 }
451 507
452 /** 508 /**
453 * Implementation of this method should be synchronized with 509 * Implementation of this method should be synchronized with
454 * [visitClassDeclaration]. 510 * [visitClassDeclaration].
455 */ 511 */
456 void visitClassDeclarationIncrementally(ClassDeclaration node) { 512 void visitClassDeclarationIncrementally(ClassDeclaration node) {
457 _isInNativeClass = node.nativeClause != null; 513 _isInNativeClass = node.nativeClause != null;
458 _enclosingClass = node.element; 514 _enclosingClass = AbstractClassElementImpl.getImpl(node.element);
459 // initialize initialFieldElementsMap 515 // initialize initialFieldElementsMap
460 if (_enclosingClass != null) { 516 if (_enclosingClass != null) {
461 List<FieldElement> fieldElements = _enclosingClass.fields; 517 List<FieldElement> fieldElements = _enclosingClass.fields;
462 _initialFieldElementsMap = new HashMap<FieldElement, INIT_STATE>(); 518 _initialFieldElementsMap = new HashMap<FieldElement, INIT_STATE>();
463 for (FieldElement fieldElement in fieldElements) { 519 for (FieldElement fieldElement in fieldElements) {
464 if (!fieldElement.isSynthetic) { 520 if (!fieldElement.isSynthetic) {
465 _initialFieldElementsMap[fieldElement] = fieldElement.initializer == 521 _initialFieldElementsMap[fieldElement] =
466 null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; 522 fieldElement.initializer == null
523 ? INIT_STATE.NOT_INIT
524 : INIT_STATE.INIT_IN_DECLARATION;
467 } 525 }
468 } 526 }
469 } 527 }
470 } 528 }
471 529
472 @override 530 @override
473 Object visitClassTypeAlias(ClassTypeAlias node) { 531 Object visitClassTypeAlias(ClassTypeAlias node) {
474 _checkForBuiltInIdentifierAsName( 532 _checkForBuiltInIdentifierAsName(
475 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); 533 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
476 ClassElement outerClassElement = _enclosingClass; 534 ClassElementImpl outerClassElement = _enclosingClass;
477 try { 535 try {
478 _enclosingClass = node.element; 536 _enclosingClass = AbstractClassElementImpl.getImpl(node.element);
479 ImplementsClause implementsClause = node.implementsClause; 537 ImplementsClause implementsClause = node.implementsClause;
480 // Only check for all of the inheritance logic around clauses if there 538 // Only check for all of the inheritance logic around clauses if there
481 // isn't an error code such as "Cannot extend double" already on the 539 // isn't an error code such as "Cannot extend double" already on the
482 // class. 540 // class.
483 if (!_checkForExtendsDisallowedClassInTypeAlias(node) && 541 if (!_checkForExtendsDisallowedClassInTypeAlias(node) &&
484 !_checkForImplementsDisallowedClass(implementsClause) && 542 !_checkForImplementsDisallowedClass(implementsClause) &&
485 !_checkForAllMixinErrorCodes(node.withClause)) { 543 !_checkForAllMixinErrorCodes(node.withClause)) {
486 _checkForExtendsDeferredClassInTypeAlias(node); 544 _checkForExtendsDeferredClassInTypeAlias(node);
487 _checkForImplementsDeferredClass(implementsClause); 545 _checkForImplementsDeferredClass(implementsClause);
488 _checkForRecursiveInterfaceInheritance(_enclosingClass); 546 _checkForRecursiveInterfaceInheritance(_enclosingClass);
(...skipping 11 matching lines...) Expand all
500 _isInComment = true; 558 _isInComment = true;
501 try { 559 try {
502 return super.visitComment(node); 560 return super.visitComment(node);
503 } finally { 561 } finally {
504 _isInComment = false; 562 _isInComment = false;
505 } 563 }
506 } 564 }
507 565
508 @override 566 @override
509 Object visitCompilationUnit(CompilationUnit node) { 567 Object visitCompilationUnit(CompilationUnit node) {
568 _checkDuplicateUnitMembers(node);
510 _checkForDeferredPrefixCollisions(node); 569 _checkForDeferredPrefixCollisions(node);
511 return super.visitCompilationUnit(node); 570 return super.visitCompilationUnit(node);
512 } 571 }
513 572
514 @override 573 @override
515 Object visitConditionalExpression(ConditionalExpression node) { 574 Object visitConditionalExpression(ConditionalExpression node) {
516 _checkForNonBoolCondition(node.condition); 575 _checkForNonBoolCondition(node.condition);
517 return super.visitConditionalExpression(node); 576 return super.visitConditionalExpression(node);
518 } 577 }
519 578
(...skipping 28 matching lines...) Expand all
548 } 607 }
549 } 608 }
550 609
551 @override 610 @override
552 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { 611 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
553 _isInConstructorInitializer = true; 612 _isInConstructorInitializer = true;
554 try { 613 try {
555 SimpleIdentifier fieldName = node.fieldName; 614 SimpleIdentifier fieldName = node.fieldName;
556 Element staticElement = fieldName.staticElement; 615 Element staticElement = fieldName.staticElement;
557 _checkForInvalidField(node, fieldName, staticElement); 616 _checkForInvalidField(node, fieldName, staticElement);
558 _checkForFieldInitializerNotAssignable(node, staticElement); 617 if (staticElement is FieldElement) {
618 _checkForFieldInitializerNotAssignable(node, staticElement);
619 }
559 return super.visitConstructorFieldInitializer(node); 620 return super.visitConstructorFieldInitializer(node);
560 } finally { 621 } finally {
561 _isInConstructorInitializer = false; 622 _isInConstructorInitializer = false;
562 } 623 }
563 } 624 }
564 625
565 @override 626 @override
566 Object visitContinueStatement(ContinueStatement node) { 627 Object visitContinueStatement(ContinueStatement node) {
567 SimpleIdentifier labelNode = node.label; 628 SimpleIdentifier labelNode = node.label;
568 if (labelNode != null) { 629 if (labelNode != null) {
(...skipping 15 matching lines...) Expand all
584 } 645 }
585 646
586 @override 647 @override
587 Object visitDoStatement(DoStatement node) { 648 Object visitDoStatement(DoStatement node) {
588 _checkForNonBoolCondition(node.condition); 649 _checkForNonBoolCondition(node.condition);
589 return super.visitDoStatement(node); 650 return super.visitDoStatement(node);
590 } 651 }
591 652
592 @override 653 @override
593 Object visitEnumDeclaration(EnumDeclaration node) { 654 Object visitEnumDeclaration(EnumDeclaration node) {
594 ClassElement outerClass = _enclosingClass; 655 ClassElement outerEnum = _enclosingEnum;
595 try { 656 try {
596 _isInNativeClass = false; 657 _enclosingEnum = node.element;
597 _enclosingClass = node.element; 658 _checkDuplicateEnumMembers(node);
598 return super.visitEnumDeclaration(node); 659 return super.visitEnumDeclaration(node);
599 } finally { 660 } finally {
600 _enclosingClass = outerClass; 661 _enclosingEnum = outerEnum;
601 } 662 }
602 } 663 }
603 664
604 @override 665 @override
605 Object visitExportDirective(ExportDirective node) { 666 Object visitExportDirective(ExportDirective node) {
606 ExportElement exportElement = node.element; 667 ExportElement exportElement = node.element;
607 if (exportElement != null) { 668 if (exportElement != null) {
608 LibraryElement exportedLibrary = exportElement.exportedLibrary; 669 LibraryElement exportedLibrary = exportElement.exportedLibrary;
609 _checkForAmbiguousExport(node, exportElement, exportedLibrary); 670 _checkForAmbiguousExport(node, exportElement, exportedLibrary);
610 _checkForExportDuplicateLibraryName(node, exportElement, exportedLibrary); 671 _checkForExportDuplicateLibraryName(node, exportElement, exportedLibrary);
611 _checkForExportInternalLibrary(node, exportElement); 672 _checkForExportInternalLibrary(node, exportElement);
612 } 673 }
613 return super.visitExportDirective(node); 674 return super.visitExportDirective(node);
614 } 675 }
615 676
616 @override 677 @override
617 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { 678 Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
618 bool wasInAsync = _inAsync; 679 bool wasInAsync = _inAsync;
619 bool wasInGenerator = _inGenerator; 680 bool wasInGenerator = _inGenerator;
620 try { 681 try {
621 _inAsync = node.isAsynchronous; 682 _inAsync = node.isAsynchronous;
622 _inGenerator = node.isGenerator; 683 _inGenerator = node.isGenerator;
623 FunctionType functionType = 684 FunctionType functionType = _enclosingFunction?.type;
624 _enclosingFunction == null ? null : _enclosingFunction.type;
625 DartType expectedReturnType = functionType == null 685 DartType expectedReturnType = functionType == null
626 ? DynamicTypeImpl.instance 686 ? DynamicTypeImpl.instance
627 : functionType.returnType; 687 : functionType.returnType;
628 _checkForReturnOfInvalidType(node.expression, expectedReturnType); 688 ExecutableElement function = _enclosingFunction;
689 bool isSetterWithImplicitReturn = function.hasImplicitReturnType &&
690 function is PropertyAccessorElement &&
691 function.isSetter;
692 if (!isSetterWithImplicitReturn) {
693 _checkForReturnOfInvalidType(node.expression, expectedReturnType);
694 }
629 return super.visitExpressionFunctionBody(node); 695 return super.visitExpressionFunctionBody(node);
630 } finally { 696 } finally {
631 _inAsync = wasInAsync; 697 _inAsync = wasInAsync;
632 _inGenerator = wasInGenerator; 698 _inGenerator = wasInGenerator;
633 } 699 }
634 } 700 }
635 701
636 @override 702 @override
703 Object visitExtendsClause(ExtendsClause node) {
704 _checkForImplicitDynamicType(node.superclass);
705 return super.visitExtendsClause(node);
706 }
707
708 @override
637 Object visitFieldDeclaration(FieldDeclaration node) { 709 Object visitFieldDeclaration(FieldDeclaration node) {
638 _isInStaticVariableDeclaration = node.isStatic; 710 _isInStaticVariableDeclaration = node.isStatic;
639 _isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration; 711 _isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration;
640 if (_isInInstanceVariableDeclaration) { 712 if (_isInInstanceVariableDeclaration) {
641 VariableDeclarationList variables = node.fields; 713 VariableDeclarationList variables = node.fields;
642 if (variables.isConst) { 714 if (variables.isConst) {
643 _errorReporter.reportErrorForToken( 715 _errorReporter.reportErrorForToken(
644 CompileTimeErrorCode.CONST_INSTANCE_FIELD, variables.keyword); 716 CompileTimeErrorCode.CONST_INSTANCE_FIELD, variables.keyword);
645 } 717 }
646 } 718 }
(...skipping 10 matching lines...) Expand all
657 Object visitFieldFormalParameter(FieldFormalParameter node) { 729 Object visitFieldFormalParameter(FieldFormalParameter node) {
658 _checkForValidField(node); 730 _checkForValidField(node);
659 _checkForConstFormalParameter(node); 731 _checkForConstFormalParameter(node);
660 _checkForPrivateOptionalParameter(node); 732 _checkForPrivateOptionalParameter(node);
661 _checkForFieldInitializingFormalRedirectingConstructor(node); 733 _checkForFieldInitializingFormalRedirectingConstructor(node);
662 _checkForTypeAnnotationDeferredClass(node.type); 734 _checkForTypeAnnotationDeferredClass(node.type);
663 return super.visitFieldFormalParameter(node); 735 return super.visitFieldFormalParameter(node);
664 } 736 }
665 737
666 @override 738 @override
739 Object visitForEachStatement(ForEachStatement node) {
740 _checkForInIterable(node);
741 return super.visitForEachStatement(node);
742 }
743
744 @override
745 Object visitFormalParameterList(FormalParameterList node) {
746 _checkDuplicateDefinitionInParameterList(node);
747 return super.visitFormalParameterList(node);
748 }
749
750 @override
751 Object visitForStatement(ForStatement node) {
752 if (node.condition != null) {
753 _checkForNonBoolCondition(node.condition);
754 }
755 if (node.variables != null) {
756 _checkDuplicateVariables(node.variables);
757 }
758 return super.visitForStatement(node);
759 }
760
761 @override
667 Object visitFunctionDeclaration(FunctionDeclaration node) { 762 Object visitFunctionDeclaration(FunctionDeclaration node) {
763 ExecutableElement functionElement = node.element;
764 if (functionElement != null &&
765 functionElement.enclosingElement is! CompilationUnitElement) {
766 _hiddenElements.declare(functionElement);
767 }
668 ExecutableElement outerFunction = _enclosingFunction; 768 ExecutableElement outerFunction = _enclosingFunction;
669 try { 769 try {
670 SimpleIdentifier identifier = node.name; 770 SimpleIdentifier identifier = node.name;
671 String methodName = ""; 771 String methodName = "";
672 if (identifier != null) { 772 if (identifier != null) {
673 methodName = identifier.name; 773 methodName = identifier.name;
674 } 774 }
675 _enclosingFunction = node.element; 775 _enclosingFunction = functionElement;
676 TypeName returnType = node.returnType; 776 TypeName returnType = node.returnType;
677 if (node.isSetter || node.isGetter) { 777 if (node.isSetter || node.isGetter) {
678 _checkForMismatchedAccessorTypes(node, methodName); 778 _checkForMismatchedAccessorTypes(node, methodName);
679 if (node.isSetter) { 779 if (node.isSetter) {
680 FunctionExpression functionExpression = node.functionExpression; 780 FunctionExpression functionExpression = node.functionExpression;
681 if (functionExpression != null) { 781 if (functionExpression != null) {
682 _checkForWrongNumberOfParametersForSetter( 782 _checkForWrongNumberOfParametersForSetter(
683 identifier, functionExpression.parameters); 783 identifier, functionExpression.parameters);
684 } 784 }
685 _checkForNonVoidReturnTypeForSetter(returnType); 785 _checkForNonVoidReturnTypeForSetter(returnType);
686 } 786 }
687 } 787 }
688 if (node.isSetter) { 788 if (node.isSetter) {
689 _checkForInvalidModifierOnBody(node.functionExpression.body, 789 _checkForInvalidModifierOnBody(node.functionExpression.body,
690 CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER); 790 CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER);
691 } 791 }
692 _checkForTypeAnnotationDeferredClass(returnType); 792 _checkForTypeAnnotationDeferredClass(returnType);
693 _checkForIllegalReturnType(returnType); 793 _checkForIllegalReturnType(returnType);
794 _checkForImplicitDynamicReturn(node, node.element);
694 return super.visitFunctionDeclaration(node); 795 return super.visitFunctionDeclaration(node);
695 } finally { 796 } finally {
696 _enclosingFunction = outerFunction; 797 _enclosingFunction = outerFunction;
697 } 798 }
698 } 799 }
699 800
700 @override 801 @override
701 Object visitFunctionExpression(FunctionExpression node) { 802 Object visitFunctionExpression(FunctionExpression node) {
702 // If this function expression is wrapped in a function declaration, don't 803 // If this function expression is wrapped in a function declaration, don't
703 // change the enclosingFunction field. 804 // change the enclosingFunction field.
(...skipping 11 matching lines...) Expand all
715 } 816 }
716 817
717 @override 818 @override
718 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { 819 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
719 Expression functionExpression = node.function; 820 Expression functionExpression = node.function;
720 DartType expressionType = functionExpression.staticType; 821 DartType expressionType = functionExpression.staticType;
721 if (!_isFunctionType(expressionType)) { 822 if (!_isFunctionType(expressionType)) {
722 _errorReporter.reportErrorForNode( 823 _errorReporter.reportErrorForNode(
723 StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 824 StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
724 functionExpression); 825 functionExpression);
826 } else if (expressionType is FunctionType) {
827 _checkTypeArguments(expressionType.element, node.typeArguments);
725 } 828 }
829 _checkForImplicitDynamicInvoke(node);
726 return super.visitFunctionExpressionInvocation(node); 830 return super.visitFunctionExpressionInvocation(node);
727 } 831 }
728 832
729 @override 833 @override
730 Object visitFunctionTypeAlias(FunctionTypeAlias node) { 834 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
731 _checkForBuiltInIdentifierAsName( 835 _checkForBuiltInIdentifierAsName(
732 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); 836 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
733 _checkForDefaultValueInFunctionTypeAlias(node); 837 _checkForDefaultValueInFunctionTypeAlias(node);
734 _checkForTypeAliasCannotReferenceItself_function(node); 838 _checkForTypeAliasCannotReferenceItself_function(node);
735 return super.visitFunctionTypeAlias(node); 839 return super.visitFunctionTypeAlias(node);
736 } 840 }
737 841
738 @override 842 @override
739 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { 843 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
740 bool old = _isInFunctionTypedFormalParameter; 844 bool old = _isInFunctionTypedFormalParameter;
741 _isInFunctionTypedFormalParameter = true; 845 _isInFunctionTypedFormalParameter = true;
742 try { 846 try {
743 _checkForTypeAnnotationDeferredClass(node.returnType); 847 _checkForTypeAnnotationDeferredClass(node.returnType);
848
849 // TODO(jmesserly): ideally we'd use _checkForImplicitDynamicReturn, and
850 // we can get the function element via `node?.element?.type?.element` but
851 // it doesn't have hasImplicitReturnType set correctly.
852 if (!_options.implicitDynamic && node.returnType == null) {
853 DartType parameterType = node.element.type;
854 if (parameterType is FunctionType &&
855 parameterType.returnType.isDynamic) {
856 _errorReporter.reportErrorForNode(
857 StrongModeCode.IMPLICIT_DYNAMIC_RETURN, node, [node.identifier]);
858 }
859 }
744 return super.visitFunctionTypedFormalParameter(node); 860 return super.visitFunctionTypedFormalParameter(node);
745 } finally { 861 } finally {
746 _isInFunctionTypedFormalParameter = old; 862 _isInFunctionTypedFormalParameter = old;
747 } 863 }
748 } 864 }
749 865
750 @override 866 @override
751 Object visitIfStatement(IfStatement node) { 867 Object visitIfStatement(IfStatement node) {
752 _checkForNonBoolCondition(node.condition); 868 _checkForNonBoolCondition(node.condition);
753 return super.visitIfStatement(node); 869 return super.visitIfStatement(node);
754 } 870 }
755 871
756 @override 872 @override
873 Object visitImplementsClause(ImplementsClause node) {
874 node.interfaces.forEach(_checkForImplicitDynamicType);
875 return super.visitImplementsClause(node);
876 }
877
878 @override
757 Object visitImportDirective(ImportDirective node) { 879 Object visitImportDirective(ImportDirective node) {
758 ImportElement importElement = node.element; 880 ImportElement importElement = node.element;
759 if (importElement != null) { 881 if (importElement != null) {
760 _checkForImportDuplicateLibraryName(node, importElement); 882 _checkForImportDuplicateLibraryName(node, importElement);
761 _checkForImportInternalLibrary(node, importElement); 883 _checkForImportInternalLibrary(node, importElement);
762 } 884 }
763 return super.visitImportDirective(node); 885 return super.visitImportDirective(node);
764 } 886 }
765 887
766 @override 888 @override
767 Object visitIndexExpression(IndexExpression node) { 889 Object visitIndexExpression(IndexExpression node) {
768 _checkForArgumentTypeNotAssignableForArgument(node.index); 890 _checkForArgumentTypeNotAssignableForArgument(node.index);
769 return super.visitIndexExpression(node); 891 return super.visitIndexExpression(node);
770 } 892 }
771 893
772 @override 894 @override
773 Object visitInstanceCreationExpression(InstanceCreationExpression node) { 895 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
774 bool wasInConstInstanceCreation = _isInConstInstanceCreation; 896 bool wasInConstInstanceCreation = _isInConstInstanceCreation;
775 _isInConstInstanceCreation = node.isConst; 897 _isInConstInstanceCreation = node.isConst;
776 try { 898 try {
777 ConstructorName constructorName = node.constructorName; 899 ConstructorName constructorName = node.constructorName;
778 TypeName typeName = constructorName.type; 900 TypeName typeName = constructorName.type;
779 DartType type = typeName.type; 901 DartType type = typeName.type;
780 if (type is InterfaceType) { 902 if (type is InterfaceType) {
781 InterfaceType interfaceType = type; 903 _checkForConstOrNewWithAbstractClass(node, typeName, type);
782 _checkForConstOrNewWithAbstractClass(node, typeName, interfaceType); 904 _checkForConstOrNewWithEnum(node, typeName, type);
783 _checkForConstOrNewWithEnum(node, typeName, interfaceType);
784 if (_isInConstInstanceCreation) { 905 if (_isInConstInstanceCreation) {
785 _checkForConstWithNonConst(node); 906 _checkForConstWithNonConst(node);
786 _checkForConstWithUndefinedConstructor( 907 _checkForConstWithUndefinedConstructor(
787 node, constructorName, typeName); 908 node, constructorName, typeName);
788 _checkForConstWithTypeParameters(typeName); 909 if (!_options.strongMode) {
910 _checkForConstWithTypeParameters(typeName);
911 }
789 _checkForConstDeferredClass(node, constructorName, typeName); 912 _checkForConstDeferredClass(node, constructorName, typeName);
790 } else { 913 } else {
791 _checkForNewWithUndefinedConstructor(node, constructorName, typeName); 914 _checkForNewWithUndefinedConstructor(node, constructorName, typeName);
792 } 915 }
793 } 916 }
917 _checkForImplicitDynamicType(typeName);
794 return super.visitInstanceCreationExpression(node); 918 return super.visitInstanceCreationExpression(node);
795 } finally { 919 } finally {
796 _isInConstInstanceCreation = wasInConstInstanceCreation; 920 _isInConstInstanceCreation = wasInConstInstanceCreation;
797 } 921 }
798 } 922 }
799 923
800 @override 924 @override
801 Object visitIsExpression(IsExpression node) { 925 Object visitIsExpression(IsExpression node) {
802 _checkForTypeAnnotationDeferredClass(node.type); 926 _checkForTypeAnnotationDeferredClass(node.type);
803 return super.visitIsExpression(node); 927 return super.visitIsExpression(node);
804 } 928 }
805 929
806 @override 930 @override
807 Object visitListLiteral(ListLiteral node) { 931 Object visitListLiteral(ListLiteral node) {
808 TypeArgumentList typeArguments = node.typeArguments; 932 TypeArgumentList typeArguments = node.typeArguments;
809 if (typeArguments != null) { 933 if (typeArguments != null) {
810 if (node.constKeyword != null) { 934 if (!_options.strongMode && node.constKeyword != null) {
811 NodeList<TypeName> arguments = typeArguments.arguments; 935 NodeList<TypeName> arguments = typeArguments.arguments;
812 if (arguments.length != 0) { 936 if (arguments.isNotEmpty) {
813 _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, 937 _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
814 CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST); 938 CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST);
815 } 939 }
816 } 940 }
817 _checkForExpectedOneListTypeArgument(node, typeArguments); 941 _checkForExpectedOneListTypeArgument(node, typeArguments);
818 _checkForListElementTypeNotAssignable(node, typeArguments);
819 } 942 }
943 _checkForImplicitDynamicTypedLiteral(node);
944 _checkForListElementTypeNotAssignable(node);
820 return super.visitListLiteral(node); 945 return super.visitListLiteral(node);
821 } 946 }
822 947
823 @override 948 @override
824 Object visitMapLiteral(MapLiteral node) { 949 Object visitMapLiteral(MapLiteral node) {
825 TypeArgumentList typeArguments = node.typeArguments; 950 TypeArgumentList typeArguments = node.typeArguments;
826 if (typeArguments != null) { 951 if (typeArguments != null) {
827 NodeList<TypeName> arguments = typeArguments.arguments; 952 NodeList<TypeName> arguments = typeArguments.arguments;
828 if (arguments.length != 0) { 953 if (!_options.strongMode && arguments.isNotEmpty) {
829 if (node.constKeyword != null) { 954 if (node.constKeyword != null) {
830 _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, 955 _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
831 CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP); 956 CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP);
832 } 957 }
833 } 958 }
834 _checkExpectedTwoMapTypeArguments(typeArguments); 959 _checkExpectedTwoMapTypeArguments(typeArguments);
835 _checkForMapTypeNotAssignable(node, typeArguments);
836 } 960 }
961 _checkForImplicitDynamicTypedLiteral(node);
962 _checkForMapTypeNotAssignable(node);
837 _checkForNonConstMapAsExpressionStatement(node); 963 _checkForNonConstMapAsExpressionStatement(node);
838 return super.visitMapLiteral(node); 964 return super.visitMapLiteral(node);
839 } 965 }
840 966
841 @override 967 @override
842 Object visitMethodDeclaration(MethodDeclaration node) { 968 Object visitMethodDeclaration(MethodDeclaration node) {
843 ExecutableElement previousFunction = _enclosingFunction; 969 ExecutableElement previousFunction = _enclosingFunction;
844 try { 970 try {
845 _isInStaticMethod = node.isStatic; 971 _isInStaticMethod = node.isStatic;
846 _enclosingFunction = node.element; 972 _enclosingFunction = node.element;
(...skipping 17 matching lines...) Expand all
864 _checkForConflictingStaticSetterAndInstanceMember(node); 990 _checkForConflictingStaticSetterAndInstanceMember(node);
865 } else if (node.isOperator) { 991 } else if (node.isOperator) {
866 _checkForOptionalParameterInOperator(node); 992 _checkForOptionalParameterInOperator(node);
867 _checkForWrongNumberOfParametersForOperator(node); 993 _checkForWrongNumberOfParametersForOperator(node);
868 _checkForNonVoidReturnTypeForOperator(node); 994 _checkForNonVoidReturnTypeForOperator(node);
869 } 995 }
870 _checkForConcreteClassWithAbstractMember(node); 996 _checkForConcreteClassWithAbstractMember(node);
871 _checkForAllInvalidOverrideErrorCodesForMethod(node); 997 _checkForAllInvalidOverrideErrorCodesForMethod(node);
872 _checkForTypeAnnotationDeferredClass(returnTypeName); 998 _checkForTypeAnnotationDeferredClass(returnTypeName);
873 _checkForIllegalReturnType(returnTypeName); 999 _checkForIllegalReturnType(returnTypeName);
1000 _checkForImplicitDynamicReturn(node, node.element);
1001 _checkForMustCallSuper(node);
874 return super.visitMethodDeclaration(node); 1002 return super.visitMethodDeclaration(node);
875 } finally { 1003 } finally {
876 _enclosingFunction = previousFunction; 1004 _enclosingFunction = previousFunction;
877 _isInStaticMethod = false; 1005 _isInStaticMethod = false;
878 } 1006 }
879 } 1007 }
880 1008
881 @override 1009 @override
882 Object visitMethodInvocation(MethodInvocation node) { 1010 Object visitMethodInvocation(MethodInvocation node) {
883 Expression target = node.realTarget; 1011 Expression target = node.realTarget;
884 SimpleIdentifier methodName = node.methodName; 1012 SimpleIdentifier methodName = node.methodName;
885 if (target != null) { 1013 if (target != null) {
886 ClassElement typeReference = ElementResolver.getTypeReference(target); 1014 ClassElement typeReference = ElementResolver.getTypeReference(target);
887 _checkForStaticAccessToInstanceMember(typeReference, methodName); 1015 _checkForStaticAccessToInstanceMember(typeReference, methodName);
888 _checkForInstanceAccessToStaticMember(typeReference, methodName); 1016 _checkForInstanceAccessToStaticMember(typeReference, methodName);
889 } else { 1017 } else {
890 _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); 1018 _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName);
891 } 1019 }
1020 _checkTypeArguments(
1021 node.methodName.staticElement, node.typeArguments, target?.staticType);
1022 _checkForImplicitDynamicInvoke(node);
892 return super.visitMethodInvocation(node); 1023 return super.visitMethodInvocation(node);
893 } 1024 }
894 1025
895 @override 1026 @override
896 Object visitNativeClause(NativeClause node) { 1027 Object visitNativeClause(NativeClause node) {
897 // TODO(brianwilkerson) Figure out the right rule for when 'native' is 1028 // TODO(brianwilkerson) Figure out the right rule for when 'native' is
898 // allowed. 1029 // allowed.
899 if (!_isInSystemLibrary) { 1030 if (!_isInSystemLibrary) {
900 _errorReporter.reportErrorForNode( 1031 _errorReporter.reportErrorForNode(
901 ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node); 1032 ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node);
902 } 1033 }
903 return super.visitNativeClause(node); 1034 return super.visitNativeClause(node);
904 } 1035 }
905 1036
906 @override 1037 @override
907 Object visitNativeFunctionBody(NativeFunctionBody node) { 1038 Object visitNativeFunctionBody(NativeFunctionBody node) {
908 _checkForNativeFunctionBodyInNonSDKCode(node); 1039 _checkForNativeFunctionBodyInNonSdkCode(node);
909 return super.visitNativeFunctionBody(node); 1040 return super.visitNativeFunctionBody(node);
910 } 1041 }
911 1042
912 @override 1043 @override
913 Object visitPostfixExpression(PostfixExpression node) { 1044 Object visitPostfixExpression(PostfixExpression node) {
914 _checkForAssignmentToFinal(node.operand); 1045 _checkForAssignmentToFinal(node.operand);
915 _checkForIntNotAssignable(node.operand); 1046 _checkForIntNotAssignable(node.operand);
916 return super.visitPostfixExpression(node); 1047 return super.visitPostfixExpression(node);
917 } 1048 }
918 1049
919 @override 1050 @override
920 Object visitPrefixedIdentifier(PrefixedIdentifier node) { 1051 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
921 if (node.parent is! Annotation) { 1052 if (node.parent is! Annotation) {
922 ClassElement typeReference = 1053 ClassElement typeReference =
923 ElementResolver.getTypeReference(node.prefix); 1054 ElementResolver.getTypeReference(node.prefix);
924 SimpleIdentifier name = node.identifier; 1055 SimpleIdentifier name = node.identifier;
925 _checkForStaticAccessToInstanceMember(typeReference, name); 1056 _checkForStaticAccessToInstanceMember(typeReference, name);
926 _checkForInstanceAccessToStaticMember(typeReference, name); 1057 _checkForInstanceAccessToStaticMember(typeReference, name);
927 } 1058 }
928 return super.visitPrefixedIdentifier(node); 1059 return super.visitPrefixedIdentifier(node);
929 } 1060 }
930 1061
931 @override 1062 @override
932 Object visitPrefixExpression(PrefixExpression node) { 1063 Object visitPrefixExpression(PrefixExpression node) {
933 sc.TokenType operatorType = node.operator.type; 1064 TokenType operatorType = node.operator.type;
934 Expression operand = node.operand; 1065 Expression operand = node.operand;
935 if (operatorType == sc.TokenType.BANG) { 1066 if (operatorType == TokenType.BANG) {
936 _checkForNonBoolNegationExpression(operand); 1067 _checkForNonBoolNegationExpression(operand);
937 } else if (operatorType.isIncrementOperator) { 1068 } else if (operatorType.isIncrementOperator) {
938 _checkForAssignmentToFinal(operand); 1069 _checkForAssignmentToFinal(operand);
939 } 1070 }
940 _checkForIntNotAssignable(operand); 1071 _checkForIntNotAssignable(operand);
941 return super.visitPrefixExpression(node); 1072 return super.visitPrefixExpression(node);
942 } 1073 }
943 1074
944 @override 1075 @override
945 Object visitPropertyAccess(PropertyAccess node) { 1076 Object visitPropertyAccess(PropertyAccess node) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 } 1108 }
978 _checkForAllReturnStatementErrorCodes(node); 1109 _checkForAllReturnStatementErrorCodes(node);
979 return super.visitReturnStatement(node); 1110 return super.visitReturnStatement(node);
980 } 1111 }
981 1112
982 @override 1113 @override
983 Object visitSimpleFormalParameter(SimpleFormalParameter node) { 1114 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
984 _checkForConstFormalParameter(node); 1115 _checkForConstFormalParameter(node);
985 _checkForPrivateOptionalParameter(node); 1116 _checkForPrivateOptionalParameter(node);
986 _checkForTypeAnnotationDeferredClass(node.type); 1117 _checkForTypeAnnotationDeferredClass(node.type);
1118
1119 // Checks for an implicit dynamic parameter type.
1120 //
1121 // We can skip other parameter kinds besides simple formal, because:
1122 // - DefaultFormalParameter contains a simple one, so it gets here,
1123 // - FieldFormalParameter error should be reported on the field,
1124 // - FunctionTypedFormalParameter is a function type, not dynamic.
1125 _checkForImplicitDynamicIdentifier(node, node.identifier);
1126
987 return super.visitSimpleFormalParameter(node); 1127 return super.visitSimpleFormalParameter(node);
988 } 1128 }
989 1129
990 @override 1130 @override
991 Object visitSimpleIdentifier(SimpleIdentifier node) { 1131 Object visitSimpleIdentifier(SimpleIdentifier node) {
1132 _checkForAmbiguousImport(node);
1133 _checkForReferenceBeforeDeclaration(node);
992 _checkForImplicitThisReferenceInInitializer(node); 1134 _checkForImplicitThisReferenceInInitializer(node);
993 if (!_isUnqualifiedReferenceToNonLocalStaticMemberAllowed(node)) { 1135 if (!_isUnqualifiedReferenceToNonLocalStaticMemberAllowed(node)) {
994 _checkForUnqualifiedReferenceToNonLocalStaticMember(node); 1136 _checkForUnqualifiedReferenceToNonLocalStaticMember(node);
995 } 1137 }
996 return super.visitSimpleIdentifier(node); 1138 return super.visitSimpleIdentifier(node);
997 } 1139 }
998 1140
999 @override 1141 @override
1000 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { 1142 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
1001 _isInConstructorInitializer = true; 1143 _isInConstructorInitializer = true;
1002 try { 1144 try {
1003 return super.visitSuperConstructorInvocation(node); 1145 return super.visitSuperConstructorInvocation(node);
1004 } finally { 1146 } finally {
1005 _isInConstructorInitializer = false; 1147 _isInConstructorInitializer = false;
1006 } 1148 }
1007 } 1149 }
1008 1150
1009 @override 1151 @override
1152 Object visitSwitchCase(SwitchCase node) {
1153 _checkDuplicateDeclarationInStatements(node.statements);
1154 return super.visitSwitchCase(node);
1155 }
1156
1157 @override
1158 Object visitSwitchDefault(SwitchDefault node) {
1159 _checkDuplicateDeclarationInStatements(node.statements);
1160 return super.visitSwitchDefault(node);
1161 }
1162
1163 @override
1010 Object visitSwitchStatement(SwitchStatement node) { 1164 Object visitSwitchStatement(SwitchStatement node) {
1011 _checkForSwitchExpressionNotAssignable(node); 1165 _checkForSwitchExpressionNotAssignable(node);
1012 _checkForCaseBlocksNotTerminated(node); 1166 _checkForCaseBlocksNotTerminated(node);
1013 _checkForMissingEnumConstantInSwitch(node); 1167 _checkForMissingEnumConstantInSwitch(node);
1014 return super.visitSwitchStatement(node); 1168 return super.visitSwitchStatement(node);
1015 } 1169 }
1016 1170
1017 @override 1171 @override
1018 Object visitThisExpression(ThisExpression node) { 1172 Object visitThisExpression(ThisExpression node) {
1019 _checkForInvalidReferenceToThis(node); 1173 _checkForInvalidReferenceToThis(node);
(...skipping 27 matching lines...) Expand all
1047 _checkForTypeParameterReferencedByStatic(node); 1201 _checkForTypeParameterReferencedByStatic(node);
1048 return super.visitTypeName(node); 1202 return super.visitTypeName(node);
1049 } 1203 }
1050 1204
1051 @override 1205 @override
1052 Object visitTypeParameter(TypeParameter node) { 1206 Object visitTypeParameter(TypeParameter node) {
1053 _checkForBuiltInIdentifierAsName(node.name, 1207 _checkForBuiltInIdentifierAsName(node.name,
1054 CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME); 1208 CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME);
1055 _checkForTypeParameterSupertypeOfItsBound(node); 1209 _checkForTypeParameterSupertypeOfItsBound(node);
1056 _checkForTypeAnnotationDeferredClass(node.bound); 1210 _checkForTypeAnnotationDeferredClass(node.bound);
1211 _checkForImplicitDynamicType(node.bound);
1057 return super.visitTypeParameter(node); 1212 return super.visitTypeParameter(node);
1058 } 1213 }
1059 1214
1060 @override 1215 @override
1216 Object visitTypeParameterList(TypeParameterList node) {
1217 _checkDuplicateDefinitionInTypeParameterList(node);
1218 return super.visitTypeParameterList(node);
1219 }
1220
1221 @override
1061 Object visitVariableDeclaration(VariableDeclaration node) { 1222 Object visitVariableDeclaration(VariableDeclaration node) {
1062 SimpleIdentifier nameNode = node.name; 1223 SimpleIdentifier nameNode = node.name;
1063 Expression initializerNode = node.initializer; 1224 Expression initializerNode = node.initializer;
1064 // do checks 1225 // do checks
1065 _checkForInvalidAssignment(nameNode, initializerNode); 1226 _checkForInvalidAssignment(nameNode, initializerNode);
1227 _checkForImplicitDynamicIdentifier(node, nameNode);
1066 // visit name 1228 // visit name
1067 nameNode.accept(this); 1229 nameNode.accept(this);
1068 // visit initializer 1230 // visit initializer
1069 String name = nameNode.name; 1231 String name = nameNode.name;
1070 _namesForReferenceToDeclaredVariableInInitializer.add(name); 1232 _namesForReferenceToDeclaredVariableInInitializer.add(name);
1071 bool wasInInstanceVariableInitializer = _isInInstanceVariableInitializer; 1233 bool wasInInstanceVariableInitializer = _isInInstanceVariableInitializer;
1072 _isInInstanceVariableInitializer = _isInInstanceVariableDeclaration; 1234 _isInInstanceVariableInitializer = _isInInstanceVariableDeclaration;
1073 try { 1235 try {
1074 if (initializerNode != null) { 1236 if (initializerNode != null) {
1075 initializerNode.accept(this); 1237 initializerNode.accept(this);
1076 } 1238 }
1077 } finally { 1239 } finally {
1078 _isInInstanceVariableInitializer = wasInInstanceVariableInitializer; 1240 _isInInstanceVariableInitializer = wasInInstanceVariableInitializer;
1079 _namesForReferenceToDeclaredVariableInInitializer.remove(name); 1241 _namesForReferenceToDeclaredVariableInInitializer.remove(name);
1080 } 1242 }
1243 // declare the variable
1244 AstNode grandparent = node.parent.parent;
1245 if (grandparent is! TopLevelVariableDeclaration &&
1246 grandparent is! FieldDeclaration) {
1247 VariableElement element = node.element;
1248 if (element != null) {
1249 _hiddenElements.declare(element);
1250 }
1251 }
1081 // done 1252 // done
1082 return null; 1253 return null;
1083 } 1254 }
1084 1255
1085 @override 1256 @override
1086 Object visitVariableDeclarationList(VariableDeclarationList node) { 1257 Object visitVariableDeclarationList(VariableDeclarationList node) {
1087 _checkForTypeAnnotationDeferredClass(node.type); 1258 _checkForTypeAnnotationDeferredClass(node.type);
1088 return super.visitVariableDeclarationList(node); 1259 return super.visitVariableDeclarationList(node);
1089 } 1260 }
1090 1261
1091 @override 1262 @override
1092 Object visitVariableDeclarationStatement(VariableDeclarationStatement node) { 1263 Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
1093 _checkForFinalNotInitialized(node.variables); 1264 _checkForFinalNotInitialized(node.variables);
1094 return super.visitVariableDeclarationStatement(node); 1265 return super.visitVariableDeclarationStatement(node);
1095 } 1266 }
1096 1267
1097 @override 1268 @override
1098 Object visitWhileStatement(WhileStatement node) { 1269 Object visitWhileStatement(WhileStatement node) {
1099 _checkForNonBoolCondition(node.condition); 1270 _checkForNonBoolCondition(node.condition);
1100 return super.visitWhileStatement(node); 1271 return super.visitWhileStatement(node);
1101 } 1272 }
1102 1273
1103 @override 1274 @override
1275 Object visitWithClause(WithClause node) {
1276 node.mixinTypes.forEach(_checkForImplicitDynamicType);
1277 return super.visitWithClause(node);
1278 }
1279
1280 @override
1104 Object visitYieldStatement(YieldStatement node) { 1281 Object visitYieldStatement(YieldStatement node) {
1105 if (_inGenerator) { 1282 if (_inGenerator) {
1106 _checkForYieldOfInvalidType(node.expression, node.star != null); 1283 _checkForYieldOfInvalidType(node.expression, node.star != null);
1107 } else { 1284 } else {
1108 CompileTimeErrorCode errorCode; 1285 CompileTimeErrorCode errorCode;
1109 if (node.star != null) { 1286 if (node.star != null) {
1110 errorCode = CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR; 1287 errorCode = CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR;
1111 } else { 1288 } else {
1112 errorCode = CompileTimeErrorCode.YIELD_IN_NON_GENERATOR; 1289 errorCode = CompileTimeErrorCode.YIELD_IN_NON_GENERATOR;
1113 } 1290 }
1114 _errorReporter.reportErrorForNode(errorCode, node); 1291 _errorReporter.reportErrorForNode(errorCode, node);
1115 } 1292 }
1116 return super.visitYieldStatement(node); 1293 return super.visitYieldStatement(node);
1117 } 1294 }
1118 1295
1119 /** 1296 /**
1297 * If the given assert [statement] specifies a message, verify that support
1298 * for assertions with messages is enabled.
1299 */
1300 void _checkAssertMessage(AssertStatement statement) {
1301 Expression expression = statement.message;
1302 if (expression != null && !enableAssertMessage) {
1303 _errorReporter.reportErrorForNode(
1304 CompileTimeErrorCode.EXTRA_ARGUMENT_TO_ASSERT, expression);
1305 }
1306 }
1307
1308 /**
1309 * Given a list of [directives] that have the same prefix, generate an error
1310 * if there is more than one import and any of those imports is deferred.
1311 *
1312 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX].
1313 */
1314 void _checkDeferredPrefixCollision(List<ImportDirective> directives) {
1315 int count = directives.length;
1316 if (count > 1) {
1317 for (int i = 0; i < count; i++) {
1318 Token deferredToken = directives[i].deferredKeyword;
1319 if (deferredToken != null) {
1320 _errorReporter.reportErrorForToken(
1321 CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken);
1322 }
1323 }
1324 }
1325 }
1326
1327 /**
1328 * Check that there are no members with the same name.
1329 */
1330 void _checkDuplicateClassMembers(ClassDeclaration node) {
1331 Map<String, Element> definedNames = new HashMap<String, Element>();
1332 Set<String> visitedFields = new HashSet<String>();
1333 for (ClassMember member in node.members) {
1334 // We ignore constructors because they are checked in the method
1335 // _checkForConflictingConstructorNameAndMember.
1336 if (member is FieldDeclaration) {
1337 for (VariableDeclaration field in member.fields.variables) {
1338 SimpleIdentifier identifier = field.name;
1339 _checkDuplicateIdentifier(definedNames, identifier);
1340 String name = identifier.name;
1341 if (!field.isFinal &&
1342 !field.isConst &&
1343 !visitedFields.contains(name)) {
1344 _checkDuplicateIdentifier(definedNames, identifier,
1345 implicitSetter: true);
1346 }
1347 visitedFields.add(name);
1348 }
1349 } else if (member is MethodDeclaration) {
1350 _checkDuplicateIdentifier(definedNames, member.name);
1351 }
1352 }
1353 }
1354
1355 /**
1356 * Check that all of the parameters have unique names.
1357 */
1358 void _checkDuplicateDeclarationInStatements(List<Statement> statements) {
1359 Map<String, Element> definedNames = new HashMap<String, Element>();
1360 for (Statement statement in statements) {
1361 if (statement is VariableDeclarationStatement) {
1362 for (VariableDeclaration variable in statement.variables.variables) {
1363 _checkDuplicateIdentifier(definedNames, variable.name);
1364 }
1365 } else if (statement is FunctionDeclarationStatement) {
1366 _checkDuplicateIdentifier(
1367 definedNames, statement.functionDeclaration.name);
1368 }
1369 }
1370 }
1371
1372 /**
1373 * Check that the exception and stack trace parameters have different names.
1374 */
1375 void _checkDuplicateDefinitionInCatchClause(CatchClause node) {
1376 SimpleIdentifier exceptionParameter = node.exceptionParameter;
1377 SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
1378 if (exceptionParameter != null && stackTraceParameter != null) {
1379 String exceptionName = exceptionParameter.name;
1380 if (exceptionName == stackTraceParameter.name) {
1381 _errorReporter.reportErrorForNode(
1382 CompileTimeErrorCode.DUPLICATE_DEFINITION,
1383 stackTraceParameter,
1384 [exceptionName]);
1385 }
1386 }
1387 }
1388
1389 /**
1390 * Check that all of the parameters have unique names.
1391 */
1392 void _checkDuplicateDefinitionInParameterList(FormalParameterList node) {
1393 Map<String, Element> definedNames = new HashMap<String, Element>();
1394 for (FormalParameter parameter in node.parameters) {
1395 _checkDuplicateIdentifier(definedNames, parameter.identifier);
1396 }
1397 }
1398
1399 /**
1400 * Check that all of the parameters have unique names.
1401 */
1402 void _checkDuplicateDefinitionInTypeParameterList(TypeParameterList node) {
1403 Map<String, Element> definedNames = new HashMap<String, Element>();
1404 for (TypeParameter parameter in node.typeParameters) {
1405 _checkDuplicateIdentifier(definedNames, parameter.name);
1406 }
1407 }
1408
1409 /**
1410 * Check that there are no members with the same name.
1411 */
1412 void _checkDuplicateEnumMembers(EnumDeclaration node) {
1413 Map<String, Element> definedNames = new HashMap<String, Element>();
1414 ClassElement element = node.element;
1415 String indexName = 'index';
1416 String valuesName = 'values';
1417 definedNames[indexName] = element.getField(indexName);
1418 definedNames[valuesName] = element.getField(valuesName);
1419 for (EnumConstantDeclaration constant in node.constants) {
1420 _checkDuplicateIdentifier(definedNames, constant.name);
1421 }
1422 }
1423
1424 /**
1425 * Check whether the given [identifier] is already in the set of
1426 * [definedNames], and produce an error if it is. If [implicitSetter] is
1427 * `true`, then the identifier represents the definition of a setter.
1428 */
1429 void _checkDuplicateIdentifier(
1430 Map<String, Element> definedNames, SimpleIdentifier identifier,
1431 {bool implicitSetter: false}) {
1432 ErrorCode getError(Element previous, Element current) {
1433 if (previous is MethodElement && current is PropertyAccessorElement) {
1434 if (current.isGetter) {
1435 return CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME;
1436 }
1437 } else if (previous is PropertyAccessorElement &&
1438 current is MethodElement) {
1439 if (previous.isGetter) {
1440 return CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME;
1441 }
1442 } else if (previous is PrefixElement) {
1443 return CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER;
1444 }
1445 return CompileTimeErrorCode.DUPLICATE_DEFINITION;
1446 }
1447
1448 Element current = identifier.staticElement;
1449 String name = identifier.name;
1450 if (current is PropertyAccessorElement && current.isSetter) {
1451 name += '=';
1452 } else if (current is MethodElement && current.isOperator && name == '-') {
1453 if (current.parameters.length == 0) {
1454 name = 'unary-';
1455 }
1456 } else if (implicitSetter) {
1457 name += '=';
1458 }
1459 Element previous = definedNames[name];
1460 if (previous != null) {
1461 _errorReporter
1462 .reportErrorForNode(getError(previous, current), identifier, [name]);
1463 } else {
1464 definedNames[name] = identifier.staticElement;
1465 }
1466 }
1467
1468 /**
1469 * Check that there are no members with the same name.
1470 */
1471 void _checkDuplicateUnitMembers(CompilationUnit node) {
1472 Map<String, Element> definedNames = new HashMap<String, Element>();
1473 void addWithoutChecking(CompilationUnitElement element) {
1474 for (PropertyAccessorElement accessor in element.accessors) {
1475 String name = accessor.name;
1476 if (accessor.isSetter) {
1477 name += '=';
1478 }
1479 definedNames[name] = accessor;
1480 }
1481 for (ClassElement type in element.enums) {
1482 definedNames[type.name] = type;
1483 }
1484 for (FunctionElement function in element.functions) {
1485 definedNames[function.name] = function;
1486 }
1487 for (FunctionTypeAliasElement alias in element.functionTypeAliases) {
1488 definedNames[alias.name] = alias;
1489 }
1490 for (TopLevelVariableElement variable in element.topLevelVariables) {
1491 definedNames[variable.name] = variable;
1492 if (!variable.isFinal && !variable.isConst) {
1493 definedNames[variable.name + '='] = variable;
1494 }
1495 }
1496 for (ClassElement type in element.types) {
1497 definedNames[type.name] = type;
1498 }
1499 }
1500
1501 for (ImportElement importElement in _currentLibrary.imports) {
1502 PrefixElement prefix = importElement.prefix;
1503 if (prefix != null) {
1504 definedNames[prefix.name] = prefix;
1505 }
1506 }
1507 CompilationUnitElement element = node.element;
1508 if (element != _currentLibrary.definingCompilationUnit) {
1509 addWithoutChecking(_currentLibrary.definingCompilationUnit);
1510 for (CompilationUnitElement part in _currentLibrary.parts) {
1511 if (element == part) {
1512 break;
1513 }
1514 addWithoutChecking(part);
1515 }
1516 }
1517 for (CompilationUnitMember member in node.declarations) {
1518 if (member is NamedCompilationUnitMember) {
1519 _checkDuplicateIdentifier(definedNames, member.name);
1520 } else if (member is TopLevelVariableDeclaration) {
1521 for (VariableDeclaration variable in member.variables.variables) {
1522 _checkDuplicateIdentifier(definedNames, variable.name);
1523 if (!variable.isFinal && !variable.isConst) {
1524 _checkDuplicateIdentifier(definedNames, variable.name,
1525 implicitSetter: true);
1526 }
1527 }
1528 }
1529 }
1530 }
1531
1532 /**
1533 * Check that the given list of variable declarations does not define multiple
1534 * variables of the same name.
1535 */
1536 void _checkDuplicateVariables(VariableDeclarationList node) {
1537 Map<String, Element> definedNames = new HashMap<String, Element>();
1538 for (VariableDeclaration variable in node.variables) {
1539 _checkDuplicateIdentifier(definedNames, variable.name);
1540 }
1541 }
1542
1543 /**
1120 * Verify that the given list of [typeArguments] contains exactly two 1544 * Verify that the given list of [typeArguments] contains exactly two
1121 * elements. 1545 * elements.
1122 * 1546 *
1123 * See [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]. 1547 * See [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS].
1124 */ 1548 */
1125 bool _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { 1549 void _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) {
1126 // check number of type arguments
1127 int num = typeArguments.arguments.length; 1550 int num = typeArguments.arguments.length;
1128 if (num == 2) { 1551 if (num != 2) {
1129 return false; 1552 _errorReporter.reportErrorForNode(
1130 } 1553 StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS,
1131 // report problem 1554 typeArguments,
1132 _errorReporter.reportErrorForNode( 1555 [num]);
1133 StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, 1556 }
1134 typeArguments, 1557 }
1135 [num]); 1558
1136 return true; 1559 /**
1137 }
1138
1139 /**
1140 * Verify that the given [constructor] declaration does not violate any of the 1560 * Verify that the given [constructor] declaration does not violate any of the
1141 * error codes relating to the initialization of fields in the enclosing 1561 * error codes relating to the initialization of fields in the enclosing
1142 * class. 1562 * class.
1143 * 1563 *
1144 * See [_initialFieldElementsMap], 1564 * See [_initialFieldElementsMap],
1145 * [StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR], and 1565 * [StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR], and
1146 * [CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES]. 1566 * [CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES].
1147 */ 1567 */
1148 bool _checkForAllFinalInitializedErrorCodes( 1568 void _checkForAllFinalInitializedErrorCodes(
1149 ConstructorDeclaration constructor) { 1569 ConstructorDeclaration constructor) {
1150 if (constructor.factoryKeyword != null || 1570 if (constructor.factoryKeyword != null ||
1151 constructor.redirectedConstructor != null || 1571 constructor.redirectedConstructor != null ||
1152 constructor.externalKeyword != null) { 1572 constructor.externalKeyword != null) {
1153 return false; 1573 return;
1154 } 1574 }
1155 // Ignore if native class. 1575 // Ignore if native class.
1156 if (_isInNativeClass) { 1576 if (_isInNativeClass) {
1157 return false; 1577 return;
1158 } 1578 }
1159 bool foundError = false; 1579
1160 HashMap<FieldElement, INIT_STATE> fieldElementsMap = 1580 HashMap<FieldElement, INIT_STATE> fieldElementsMap =
1161 new HashMap<FieldElement, INIT_STATE>.from(_initialFieldElementsMap); 1581 new HashMap<FieldElement, INIT_STATE>.from(_initialFieldElementsMap);
1162 // Visit all of the field formal parameters 1582 // Visit all of the field formal parameters
1163 NodeList<FormalParameter> formalParameters = 1583 NodeList<FormalParameter> formalParameters =
1164 constructor.parameters.parameters; 1584 constructor.parameters.parameters;
1165 for (FormalParameter formalParameter in formalParameters) { 1585 for (FormalParameter formalParameter in formalParameters) {
1166 FormalParameter parameter = formalParameter; 1586 FormalParameter baseParameter(FormalParameter parameter) {
1167 if (parameter is DefaultFormalParameter) { 1587 if (parameter is DefaultFormalParameter) {
1168 parameter = (parameter as DefaultFormalParameter).parameter; 1588 return parameter.parameter;
1589 }
1590 return parameter;
1169 } 1591 }
1592
1593 FormalParameter parameter = baseParameter(formalParameter);
1170 if (parameter is FieldFormalParameter) { 1594 if (parameter is FieldFormalParameter) {
1171 FieldElement fieldElement = 1595 FieldElement fieldElement =
1172 (parameter.element as FieldFormalParameterElementImpl).field; 1596 (parameter.element as FieldFormalParameterElementImpl).field;
1173 INIT_STATE state = fieldElementsMap[fieldElement]; 1597 INIT_STATE state = fieldElementsMap[fieldElement];
1174 if (state == INIT_STATE.NOT_INIT) { 1598 if (state == INIT_STATE.NOT_INIT) {
1175 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL; 1599 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL;
1176 } else if (state == INIT_STATE.INIT_IN_DECLARATION) { 1600 } else if (state == INIT_STATE.INIT_IN_DECLARATION) {
1177 if (fieldElement.isFinal || fieldElement.isConst) { 1601 if (fieldElement.isFinal || fieldElement.isConst) {
1178 _errorReporter.reportErrorForNode( 1602 _errorReporter.reportErrorForNode(
1179 StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCT OR, 1603 StaticWarningCode
1604 .FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR,
1180 formalParameter.identifier, 1605 formalParameter.identifier,
1181 [fieldElement.displayName]); 1606 [fieldElement.displayName]);
1182 foundError = true;
1183 } 1607 }
1184 } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) { 1608 } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) {
1185 if (fieldElement.isFinal || fieldElement.isConst) { 1609 if (fieldElement.isFinal || fieldElement.isConst) {
1186 _errorReporter.reportErrorForNode( 1610 _errorReporter.reportErrorForNode(
1187 CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, 1611 CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES,
1188 formalParameter.identifier, 1612 formalParameter.identifier,
1189 [fieldElement.displayName]); 1613 [fieldElement.displayName]);
1190 foundError = true;
1191 } 1614 }
1192 } 1615 }
1193 } 1616 }
1194 } 1617 }
1195 // Visit all of the initializers 1618 // Visit all of the initializers
1196 NodeList<ConstructorInitializer> initializers = constructor.initializers; 1619 NodeList<ConstructorInitializer> initializers = constructor.initializers;
1197 for (ConstructorInitializer constructorInitializer in initializers) { 1620 for (ConstructorInitializer constructorInitializer in initializers) {
1198 if (constructorInitializer is RedirectingConstructorInvocation) { 1621 if (constructorInitializer is RedirectingConstructorInvocation) {
1199 return false; 1622 return;
1200 } 1623 }
1201 if (constructorInitializer is ConstructorFieldInitializer) { 1624 if (constructorInitializer is ConstructorFieldInitializer) {
1202 ConstructorFieldInitializer constructorFieldInitializer = 1625 SimpleIdentifier fieldName = constructorInitializer.fieldName;
1203 constructorInitializer;
1204 SimpleIdentifier fieldName = constructorFieldInitializer.fieldName;
1205 Element element = fieldName.staticElement; 1626 Element element = fieldName.staticElement;
1206 if (element is FieldElement) { 1627 if (element is FieldElement) {
1207 FieldElement fieldElement = element; 1628 INIT_STATE state = fieldElementsMap[element];
1208 INIT_STATE state = fieldElementsMap[fieldElement];
1209 if (state == INIT_STATE.NOT_INIT) { 1629 if (state == INIT_STATE.NOT_INIT) {
1210 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_INITIALIZERS; 1630 fieldElementsMap[element] = INIT_STATE.INIT_IN_INITIALIZERS;
1211 } else if (state == INIT_STATE.INIT_IN_DECLARATION) { 1631 } else if (state == INIT_STATE.INIT_IN_DECLARATION) {
1212 if (fieldElement.isFinal || fieldElement.isConst) { 1632 if (element.isFinal || element.isConst) {
1213 _errorReporter.reportErrorForNode( 1633 _errorReporter.reportErrorForNode(
1214 StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARA TION, 1634 StaticWarningCode
1635 .FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION,
1215 fieldName); 1636 fieldName);
1216 foundError = true;
1217 } 1637 }
1218 } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) { 1638 } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) {
1219 _errorReporter.reportErrorForNode( 1639 _errorReporter.reportErrorForNode(
1220 CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALI ZER, 1640 CompileTimeErrorCode
1641 .FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER,
1221 fieldName); 1642 fieldName);
1222 foundError = true;
1223 } else if (state == INIT_STATE.INIT_IN_INITIALIZERS) { 1643 } else if (state == INIT_STATE.INIT_IN_INITIALIZERS) {
1224 _errorReporter.reportErrorForNode( 1644 _errorReporter.reportErrorForNode(
1225 CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS, 1645 CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
1226 fieldName, 1646 fieldName,
1227 [fieldElement.displayName]); 1647 [element.displayName]);
1228 foundError = true;
1229 } 1648 }
1230 } 1649 }
1231 } 1650 }
1232 } 1651 }
1233 // Prepare a list of not initialized fields. 1652 // Prepare a list of not initialized fields.
1234 List<FieldElement> notInitFinalFields = <FieldElement>[]; 1653 List<FieldElement> notInitFinalFields = <FieldElement>[];
1235 fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) { 1654 fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) {
1236 if (state == INIT_STATE.NOT_INIT) { 1655 if (state == INIT_STATE.NOT_INIT) {
1237 if (fieldElement.isFinal) { 1656 if (fieldElement.isFinal) {
1238 notInitFinalFields.add(fieldElement); 1657 notInitFinalFields.add(fieldElement);
1239 } 1658 }
1240 } 1659 }
1241 }); 1660 });
1242 // Visit all of the states in the map to ensure that none were never 1661 // Visit all of the states in the map to ensure that none were never
1243 // initialized. 1662 // initialized.
1244 fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) { 1663 fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) {
1245 if (state == INIT_STATE.NOT_INIT) { 1664 if (state == INIT_STATE.NOT_INIT) {
1246 if (fieldElement.isConst) { 1665 if (fieldElement.isConst) {
1247 _errorReporter.reportErrorForNode( 1666 _errorReporter.reportErrorForNode(
1248 CompileTimeErrorCode.CONST_NOT_INITIALIZED, 1667 CompileTimeErrorCode.CONST_NOT_INITIALIZED,
1249 constructor.returnType, 1668 constructor.returnType,
1250 [fieldElement.name]); 1669 [fieldElement.name]);
1251 foundError = true;
1252 } 1670 }
1253 } 1671 }
1254 }); 1672 });
1673
1255 if (notInitFinalFields.isNotEmpty) { 1674 if (notInitFinalFields.isNotEmpty) {
1256 foundError = true;
1257 AnalysisErrorWithProperties analysisError; 1675 AnalysisErrorWithProperties analysisError;
1258 if (notInitFinalFields.length == 1) { 1676 List<String> names = notInitFinalFields.map((item) => item.name).toList();
1677 names.sort();
1678 if (names.length == 1) {
1259 analysisError = _errorReporter.newErrorWithProperties( 1679 analysisError = _errorReporter.newErrorWithProperties(
1260 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1, 1680 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1,
1261 constructor.returnType, 1681 constructor.returnType,
1262 [notInitFinalFields[0].name]); 1682 names);
1263 } else if (notInitFinalFields.length == 2) { 1683 } else if (names.length == 2) {
1264 analysisError = _errorReporter.newErrorWithProperties( 1684 analysisError = _errorReporter.newErrorWithProperties(
1265 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2, 1685 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2,
1266 constructor.returnType, 1686 constructor.returnType,
1267 [notInitFinalFields[0].name, notInitFinalFields[1].name]); 1687 names);
1268 } else { 1688 } else {
1269 analysisError = _errorReporter.newErrorWithProperties( 1689 analysisError = _errorReporter.newErrorWithProperties(
1270 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS, 1690 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS,
1271 constructor.returnType, [ 1691 constructor.returnType,
1272 notInitFinalFields[0].name, 1692 [names[0], names[1], names.length - 2]);
1273 notInitFinalFields[1].name,
1274 notInitFinalFields.length - 2
1275 ]);
1276 } 1693 }
1277 analysisError.setProperty( 1694 analysisError.setProperty(
1278 ErrorProperty.NOT_INITIALIZED_FIELDS, notInitFinalFields); 1695 ErrorProperty.NOT_INITIALIZED_FIELDS, notInitFinalFields);
1279 _errorReporter.reportError(analysisError); 1696 _errorReporter.reportError(analysisError);
1280 } 1697 }
1281 return foundError;
1282 } 1698 }
1283 1699
1284 /** 1700 /**
1285 * Check the given [executableElement] against override-error codes. The 1701 * Check the given [derivedElement] against override-error codes. The
1286 * [overriddenExecutable] is the element that the executable element is 1702 * [baseElement] is the element that the executable element is
1287 * overriding. The [parameters] is the parameters of the executable element. 1703 * overriding. The [parameters] is the parameters of the executable element.
1288 * The [errorNameTarget] is the node to report problems on. 1704 * The [errorNameTarget] is the node to report problems on.
1289 * 1705 *
1290 * See [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC ], 1706 * See [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC ],
1291 * [CompileTimeErrorCode.INVALID_OVERRIDE_REQUIRED], 1707 * [CompileTimeErrorCode.INVALID_OVERRIDE_REQUIRED],
1292 * [CompileTimeErrorCode.INVALID_OVERRIDE_POSITIONAL], 1708 * [CompileTimeErrorCode.INVALID_OVERRIDE_POSITIONAL],
1293 * [CompileTimeErrorCode.INVALID_OVERRIDE_NAMED], 1709 * [CompileTimeErrorCode.INVALID_OVERRIDE_NAMED],
1294 * [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE], 1710 * [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE],
1295 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE], 1711 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE],
1296 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE], 1712 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE],
1297 * [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE], 1713 * [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE],
1298 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE], 1714 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE],
1299 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE], and 1715 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE], and
1300 * [StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES]. 1716 * [StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES].
1301 */ 1717 */
1302 bool _checkForAllInvalidOverrideErrorCodes( 1718 bool _checkForAllInvalidOverrideErrorCodes(
1303 ExecutableElement executableElement, 1719 ExecutableElement derivedElement,
1304 ExecutableElement overriddenExecutable, 1720 ExecutableElement baseElement,
1305 List<ParameterElement> parameters, 1721 List<ParameterElement> parameters,
1306 List<AstNode> parameterLocations, 1722 List<AstNode> parameterLocations,
1307 SimpleIdentifier errorNameTarget) { 1723 SimpleIdentifier errorNameTarget) {
1724 if (_options.strongMode) {
1725 return false; // strong mode already checked for this
1726 }
1727
1308 bool isGetter = false; 1728 bool isGetter = false;
1309 bool isSetter = false; 1729 bool isSetter = false;
1310 if (executableElement is PropertyAccessorElement) { 1730 if (derivedElement is PropertyAccessorElement) {
1311 PropertyAccessorElement accessorElement = executableElement; 1731 isGetter = derivedElement.isGetter;
1312 isGetter = accessorElement.isGetter; 1732 isSetter = derivedElement.isSetter;
1313 isSetter = accessorElement.isSetter;
1314 } 1733 }
1315 String executableElementName = executableElement.name; 1734 String executableElementName = derivedElement.name;
1316 FunctionType overridingFT = executableElement.type; 1735 FunctionType derivedFT = derivedElement.type;
1317 FunctionType overriddenFT = overriddenExecutable.type; 1736 FunctionType baseFT = baseElement.type;
1318 InterfaceType enclosingType = _enclosingClass.type; 1737 InterfaceType enclosingType = _enclosingClass.type;
1319 overriddenFT = _inheritanceManager 1738 baseFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(
1320 .substituteTypeArgumentsInMemberFromInheritance( 1739 baseFT, executableElementName, enclosingType);
1321 overriddenFT, executableElementName, enclosingType); 1740 if (derivedFT == null || baseFT == null) {
1322 if (overridingFT == null || overriddenFT == null) {
1323 return false; 1741 return false;
1324 } 1742 }
1325 DartType overridingFTReturnType = overridingFT.returnType; 1743
1326 DartType overriddenFTReturnType = overriddenFT.returnType; 1744 // Handle generic function type parameters.
1327 List<DartType> overridingNormalPT = overridingFT.normalParameterTypes; 1745 // TODO(jmesserly): this duplicates some code in isSubtypeOf and most of
1328 List<DartType> overriddenNormalPT = overriddenFT.normalParameterTypes; 1746 // _isGenericFunctionSubtypeOf. Ideally, we'd let TypeSystem produce
1329 List<DartType> overridingPositionalPT = overridingFT.optionalParameterTypes; 1747 // an error message once it's ready to "return false".
1330 List<DartType> overriddenPositionalPT = overriddenFT.optionalParameterTypes; 1748 if (!derivedFT.typeFormals.isEmpty) {
1331 Map<String, DartType> overridingNamedPT = overridingFT.namedParameterTypes; 1749 if (baseFT.typeFormals.isEmpty) {
1332 Map<String, DartType> overriddenNamedPT = overriddenFT.namedParameterTypes; 1750 derivedFT = _typeSystem.instantiateToBounds(derivedFT);
1751 } else {
1752 List<TypeParameterElement> params1 = derivedFT.typeFormals;
1753 List<TypeParameterElement> params2 = baseFT.typeFormals;
1754 int count = params1.length;
1755 if (params2.length != count) {
1756 _errorReporter.reportErrorForNode(
1757 StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS,
1758 errorNameTarget, [
1759 count,
1760 params2.length,
1761 baseElement.enclosingElement.displayName
1762 ]);
1763 return true;
1764 }
1765 // We build up a substitution matching up the type parameters
1766 // from the two types, {variablesFresh/variables1} and
1767 // {variablesFresh/variables2}
1768 List<DartType> variables1 = new List<DartType>();
1769 List<DartType> variables2 = new List<DartType>();
1770 List<DartType> variablesFresh = new List<DartType>();
1771 for (int i = 0; i < count; i++) {
1772 TypeParameterElement p1 = params1[i];
1773 TypeParameterElement p2 = params2[i];
1774 TypeParameterElementImpl pFresh =
1775 new TypeParameterElementImpl(p1.name, -1);
1776
1777 DartType variable1 = p1.type;
1778 DartType variable2 = p2.type;
1779 DartType variableFresh = new TypeParameterTypeImpl(pFresh);
1780
1781 variables1.add(variable1);
1782 variables2.add(variable2);
1783 variablesFresh.add(variableFresh);
1784 DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
1785 DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
1786 bound1 = bound1.substitute2(variablesFresh, variables1);
1787 bound2 = bound2.substitute2(variablesFresh, variables2);
1788 pFresh.bound = bound2;
1789 if (!_typeSystem.isSubtypeOf(bound2, bound1)) {
1790 _errorReporter.reportErrorForNode(
1791 StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND,
1792 errorNameTarget, [
1793 p1.displayName,
1794 p1.bound,
1795 p2.displayName,
1796 p2.bound,
1797 baseElement.enclosingElement.displayName
1798 ]);
1799 return true;
1800 }
1801 }
1802 // Proceed with the rest of the checks, using instantiated types.
1803 derivedFT = derivedFT.instantiate(variablesFresh);
1804 baseFT = baseFT.instantiate(variablesFresh);
1805 }
1806 }
1807
1808 DartType derivedFTReturnType = derivedFT.returnType;
1809 DartType baseFTReturnType = baseFT.returnType;
1810 List<DartType> derivedNormalPT = derivedFT.normalParameterTypes;
1811 List<DartType> baseNormalPT = baseFT.normalParameterTypes;
1812 List<DartType> derivedPositionalPT = derivedFT.optionalParameterTypes;
1813 List<DartType> basePositionalPT = baseFT.optionalParameterTypes;
1814 Map<String, DartType> derivedNamedPT = derivedFT.namedParameterTypes;
1815 Map<String, DartType> baseNamedPT = baseFT.namedParameterTypes;
1333 // CTEC.INVALID_OVERRIDE_REQUIRED, CTEC.INVALID_OVERRIDE_POSITIONAL and 1816 // CTEC.INVALID_OVERRIDE_REQUIRED, CTEC.INVALID_OVERRIDE_POSITIONAL and
1334 // CTEC.INVALID_OVERRIDE_NAMED 1817 // CTEC.INVALID_OVERRIDE_NAMED
1335 if (overridingNormalPT.length > overriddenNormalPT.length) { 1818 if (derivedNormalPT.length > baseNormalPT.length) {
1336 _errorReporter.reportErrorForNode( 1819 _errorReporter.reportErrorForNode(
1337 StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [ 1820 StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [
1338 overriddenNormalPT.length, 1821 baseNormalPT.length,
1339 overriddenExecutable.enclosingElement.displayName 1822 baseElement,
1823 baseElement.enclosingElement.displayName
1340 ]); 1824 ]);
1341 return true; 1825 return true;
1342 } 1826 }
1343 if (overridingNormalPT.length + overridingPositionalPT.length < 1827 if (derivedNormalPT.length + derivedPositionalPT.length <
1344 overriddenPositionalPT.length + overriddenNormalPT.length) { 1828 basePositionalPT.length + baseNormalPT.length) {
1345 _errorReporter.reportErrorForNode( 1829 _errorReporter.reportErrorForNode(
1346 StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [ 1830 StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [
1347 overriddenPositionalPT.length + overriddenNormalPT.length, 1831 basePositionalPT.length + baseNormalPT.length,
1348 overriddenExecutable.enclosingElement.displayName 1832 baseElement,
1833 baseElement.enclosingElement.displayName
1349 ]); 1834 ]);
1350 return true; 1835 return true;
1351 } 1836 }
1352 // For each named parameter in the overridden method, verify that there is 1837 // For each named parameter in the overridden method, verify that there is
1353 // the same name in the overriding method. 1838 // the same name in the overriding method.
1354 for (String overriddenParamName in overriddenNamedPT.keys) { 1839 for (String overriddenParamName in baseNamedPT.keys) {
1355 if (!overridingNamedPT.containsKey(overriddenParamName)) { 1840 if (!derivedNamedPT.containsKey(overriddenParamName)) {
1356 // The overridden method expected the overriding method to have 1841 // The overridden method expected the overriding method to have
1357 // overridingParamName, but it does not. 1842 // overridingParamName, but it does not.
1358 _errorReporter.reportErrorForNode( 1843 _errorReporter.reportErrorForNode(
1359 StaticWarningCode.INVALID_OVERRIDE_NAMED, errorNameTarget, [ 1844 StaticWarningCode.INVALID_OVERRIDE_NAMED, errorNameTarget, [
1360 overriddenParamName, 1845 overriddenParamName,
1361 overriddenExecutable.enclosingElement.displayName 1846 baseElement,
1847 baseElement.enclosingElement.displayName
1362 ]); 1848 ]);
1363 return true; 1849 return true;
1364 } 1850 }
1365 } 1851 }
1366 // SWC.INVALID_METHOD_OVERRIDE_RETURN_TYPE 1852 // SWC.INVALID_METHOD_OVERRIDE_RETURN_TYPE
1367 if (overriddenFTReturnType != VoidTypeImpl.instance && 1853 if (baseFTReturnType != VoidTypeImpl.instance &&
1368 !_typeSystem.isAssignableTo( 1854 !_typeSystem.isAssignableTo(derivedFTReturnType, baseFTReturnType)) {
1369 overridingFTReturnType, overriddenFTReturnType)) {
1370 _errorReporter.reportTypeErrorForNode( 1855 _errorReporter.reportTypeErrorForNode(
1371 !isGetter 1856 !isGetter
1372 ? StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE 1857 ? StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE
1373 : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, 1858 : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE,
1374 errorNameTarget, 1859 errorNameTarget,
1375 [ 1860 [
1376 overridingFTReturnType, 1861 derivedFTReturnType,
1377 overriddenFTReturnType, 1862 baseFTReturnType,
1378 overriddenExecutable.enclosingElement.displayName 1863 baseElement.enclosingElement.displayName
1379 ]); 1864 ]);
1380 return true; 1865 return true;
1381 } 1866 }
1382 // SWC.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE 1867 // SWC.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
1383 if (parameterLocations == null) { 1868 if (parameterLocations == null) {
1384 return false; 1869 return false;
1385 } 1870 }
1386 int parameterIndex = 0; 1871 int parameterIndex = 0;
1387 for (int i = 0; i < overridingNormalPT.length; i++) { 1872 for (int i = 0; i < derivedNormalPT.length; i++) {
1388 if (!_typeSystem.isAssignableTo( 1873 if (!_typeSystem.isAssignableTo(baseNormalPT[i], derivedNormalPT[i])) {
1389 overridingNormalPT[i], overriddenNormalPT[i])) {
1390 _errorReporter.reportTypeErrorForNode( 1874 _errorReporter.reportTypeErrorForNode(
1391 !isSetter 1875 !isSetter
1392 ? StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE 1876 ? StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
1393 : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE, 1877 : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE,
1394 parameterLocations[parameterIndex], 1878 parameterLocations[parameterIndex],
1395 [ 1879 [
1396 overridingNormalPT[i], 1880 derivedNormalPT[i],
1397 overriddenNormalPT[i], 1881 baseNormalPT[i],
1398 overriddenExecutable.enclosingElement.displayName 1882 baseElement.enclosingElement.displayName
1399 ]); 1883 ]);
1400 return true; 1884 return true;
1401 } 1885 }
1402 parameterIndex++; 1886 parameterIndex++;
1403 } 1887 }
1404 // SWC.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE 1888 // SWC.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE
1405 for (int i = 0; i < overriddenPositionalPT.length; i++) { 1889 for (int i = 0; i < basePositionalPT.length; i++) {
1406 if (!_typeSystem.isAssignableTo( 1890 if (!_typeSystem.isAssignableTo(
1407 overridingPositionalPT[i], overriddenPositionalPT[i])) { 1891 basePositionalPT[i], derivedPositionalPT[i])) {
1408 _errorReporter.reportTypeErrorForNode( 1892 _errorReporter.reportTypeErrorForNode(
1409 StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE, 1893 StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE,
1410 parameterLocations[parameterIndex], [ 1894 parameterLocations[parameterIndex], [
1411 overridingPositionalPT[i], 1895 derivedPositionalPT[i],
1412 overriddenPositionalPT[i], 1896 basePositionalPT[i],
1413 overriddenExecutable.enclosingElement.displayName 1897 baseElement.enclosingElement.displayName
1414 ]); 1898 ]);
1415 return true; 1899 return true;
1416 } 1900 }
1417 parameterIndex++; 1901 parameterIndex++;
1418 } 1902 }
1419 // SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE & 1903 // SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE &
1420 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES 1904 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
1421 for (String overriddenName in overriddenNamedPT.keys) { 1905 for (String overriddenName in baseNamedPT.keys) {
1422 DartType overridingType = overridingNamedPT[overriddenName]; 1906 DartType derivedType = derivedNamedPT[overriddenName];
1423 if (overridingType == null) { 1907 if (derivedType == null) {
1424 // Error, this is never reached- INVALID_OVERRIDE_NAMED would have been 1908 // Error, this is never reached- INVALID_OVERRIDE_NAMED would have been
1425 // created above if this could be reached. 1909 // created above if this could be reached.
1426 continue; 1910 continue;
1427 } 1911 }
1428 DartType overriddenType = overriddenNamedPT[overriddenName]; 1912 DartType baseType = baseNamedPT[overriddenName];
1429 if (!_typeSystem.isAssignableTo(overriddenType, overridingType)) { 1913 if (!_typeSystem.isAssignableTo(baseType, derivedType)) {
1430 // lookup the parameter for the error to select 1914 // lookup the parameter for the error to select
1431 ParameterElement parameterToSelect = null; 1915 ParameterElement parameterToSelect = null;
1432 AstNode parameterLocationToSelect = null; 1916 AstNode parameterLocationToSelect = null;
1433 for (int i = 0; i < parameters.length; i++) { 1917 for (int i = 0; i < parameters.length; i++) {
1434 ParameterElement parameter = parameters[i]; 1918 ParameterElement parameter = parameters[i];
1435 if (parameter.parameterKind == ParameterKind.NAMED && 1919 if (parameter.parameterKind == ParameterKind.NAMED &&
1436 overriddenName == parameter.name) { 1920 overriddenName == parameter.name) {
1437 parameterToSelect = parameter; 1921 parameterToSelect = parameter;
1438 parameterLocationToSelect = parameterLocations[i]; 1922 parameterLocationToSelect = parameterLocations[i];
1439 break; 1923 break;
1440 } 1924 }
1441 } 1925 }
1442 if (parameterToSelect != null) { 1926 if (parameterToSelect != null) {
1443 _errorReporter.reportTypeErrorForNode( 1927 _errorReporter.reportTypeErrorForNode(
1444 StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE, 1928 StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE,
1445 parameterLocationToSelect, [ 1929 parameterLocationToSelect, [
1446 overridingType, 1930 derivedType,
1447 overriddenType, 1931 baseType,
1448 overriddenExecutable.enclosingElement.displayName 1932 baseElement.enclosingElement.displayName
1449 ]); 1933 ]);
1450 return true; 1934 return true;
1451 } 1935 }
1452 } 1936 }
1453 } 1937 }
1454 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES 1938 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
1455 // 1939 //
1456 // Create three lists: a list of the optional parameter ASTs 1940 // Create three lists: a list of the optional parameter ASTs
1457 // (FormalParameters), a list of the optional parameters elements from our 1941 // (FormalParameters), a list of the optional parameters elements from our
1458 // method, and finally a list of the optional parameter elements from the 1942 // method, and finally a list of the optional parameter elements from the
1459 // method we are overriding. 1943 // method we are overriding.
1460 // 1944 //
1461 bool foundError = false; 1945 bool foundError = false;
1462 List<AstNode> formalParameters = new List<AstNode>(); 1946 List<AstNode> formalParameters = new List<AstNode>();
1463 List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>(); 1947 List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>();
1464 List<ParameterElementImpl> overriddenParameterElts = 1948 List<ParameterElementImpl> overriddenParameterElts =
1465 new List<ParameterElementImpl>(); 1949 new List<ParameterElementImpl>();
1466 List<ParameterElement> overriddenPEs = overriddenExecutable.parameters; 1950 List<ParameterElement> overriddenPEs = baseElement.parameters;
1467 for (int i = 0; i < parameters.length; i++) { 1951 for (int i = 0; i < parameters.length; i++) {
1468 ParameterElement parameter = parameters[i]; 1952 ParameterElement parameter = parameters[i];
1469 if (parameter.parameterKind.isOptional) { 1953 if (parameter.parameterKind.isOptional) {
1470 formalParameters.add(parameterLocations[i]); 1954 formalParameters.add(parameterLocations[i]);
1471 parameterElts.add(parameter as ParameterElementImpl); 1955 parameterElts.add(parameter as ParameterElementImpl);
1472 } 1956 }
1473 } 1957 }
1474 for (ParameterElement parameterElt in overriddenPEs) { 1958 for (ParameterElement parameterElt in overriddenPEs) {
1475 if (parameterElt.parameterKind.isOptional) { 1959 if (parameterElt.parameterKind.isOptional) {
1476 if (parameterElt is ParameterElementImpl) { 1960 if (parameterElt is ParameterElementImpl) {
(...skipping 28 matching lines...) Expand all
1505 String overriddenParameterName = overriddenParameterElt.name; 1989 String overriddenParameterName = overriddenParameterElt.name;
1506 if (parameterName != null && 1990 if (parameterName != null &&
1507 parameterName == overriddenParameterName) { 1991 parameterName == overriddenParameterName) {
1508 EvaluationResultImpl overriddenResult = 1992 EvaluationResultImpl overriddenResult =
1509 overriddenParameterElt.evaluationResult; 1993 overriddenParameterElt.evaluationResult;
1510 if (_isUserDefinedObject(overriddenResult)) { 1994 if (_isUserDefinedObject(overriddenResult)) {
1511 break; 1995 break;
1512 } 1996 }
1513 if (!result.equalValues(_typeProvider, overriddenResult)) { 1997 if (!result.equalValues(_typeProvider, overriddenResult)) {
1514 _errorReporter.reportErrorForNode( 1998 _errorReporter.reportErrorForNode(
1515 StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_ NAMED, 1999 StaticWarningCode
1516 formalParameters[i], [ 2000 .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
1517 overriddenExecutable.enclosingElement.displayName, 2001 formalParameters[i],
1518 overriddenExecutable.displayName, 2002 [
1519 parameterName 2003 baseElement.enclosingElement.displayName,
1520 ]); 2004 baseElement.displayName,
2005 parameterName
2006 ]);
1521 foundError = true; 2007 foundError = true;
1522 } 2008 }
1523 } 2009 }
1524 } 2010 }
1525 } 2011 }
1526 } else { 2012 } else {
1527 // Positional parameters, consider the positions when matching the 2013 // Positional parameters, consider the positions when matching the
1528 // parameterElts to the overriddenParameterElts 2014 // parameterElts to the overriddenParameterElts
1529 for (int i = 0; 2015 for (int i = 0;
1530 i < parameterElts.length && i < overriddenParameterElts.length; 2016 i < parameterElts.length && i < overriddenParameterElts.length;
(...skipping 11 matching lines...) Expand all
1542 // default. 2028 // default.
1543 continue; 2029 continue;
1544 } 2030 }
1545 EvaluationResultImpl overriddenResult = 2031 EvaluationResultImpl overriddenResult =
1546 overriddenParameterElt.evaluationResult; 2032 overriddenParameterElt.evaluationResult;
1547 if (_isUserDefinedObject(overriddenResult)) { 2033 if (_isUserDefinedObject(overriddenResult)) {
1548 continue; 2034 continue;
1549 } 2035 }
1550 if (!result.equalValues(_typeProvider, overriddenResult)) { 2036 if (!result.equalValues(_typeProvider, overriddenResult)) {
1551 _errorReporter.reportErrorForNode( 2037 _errorReporter.reportErrorForNode(
1552 StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSI TIONAL, 2038 StaticWarningCode
1553 formalParameters[i], [ 2039 .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
1554 overriddenExecutable.enclosingElement.displayName, 2040 formalParameters[i],
1555 overriddenExecutable.displayName 2041 [
1556 ]); 2042 baseElement.enclosingElement.displayName,
2043 baseElement.displayName
2044 ]);
1557 foundError = true; 2045 foundError = true;
1558 } 2046 }
1559 } 2047 }
1560 } 2048 }
1561 } 2049 }
1562 return foundError; 2050 return foundError;
1563 } 2051 }
1564 2052
1565 /** 2053 /**
1566 * Check the given [executableElement] against override-error codes. This 2054 * Check the given [executableElement] against override-error codes. This
1567 * method computes the given executableElement is overriding and calls 2055 * method computes the given executableElement is overriding and calls
1568 * [_checkForAllInvalidOverrideErrorCodes] when the [InheritanceManager] 2056 * [_checkForAllInvalidOverrideErrorCodes] when the [InheritanceManager]
1569 * returns a [MultiplyInheritedExecutableElement], this method loops through 2057 * returns a [MultiplyInheritedExecutableElement], this method loops through
1570 * the list in the [MultiplyInheritedExecutableElement]. The [parameters] are 2058 * the list in the [MultiplyInheritedExecutableElement]. The [parameters] are
1571 * the parameters of the executable element. The [errorNameTarget] is the node 2059 * the parameters of the executable element. The [errorNameTarget] is the node
1572 * to report problems on. 2060 * to report problems on.
1573 */ 2061 */
1574 bool _checkForAllInvalidOverrideErrorCodesForExecutable( 2062 void _checkForAllInvalidOverrideErrorCodesForExecutable(
1575 ExecutableElement executableElement, 2063 ExecutableElement executableElement,
1576 List<ParameterElement> parameters, 2064 List<ParameterElement> parameters,
1577 List<AstNode> parameterLocations, 2065 List<AstNode> parameterLocations,
1578 SimpleIdentifier errorNameTarget) { 2066 SimpleIdentifier errorNameTarget) {
2067 assert(!_options.strongMode); // strong mode already checked for these
1579 // 2068 //
1580 // Compute the overridden executable from the InheritanceManager 2069 // Compute the overridden executable from the InheritanceManager
1581 // 2070 //
1582 List<ExecutableElement> overriddenExecutables = _inheritanceManager 2071 List<ExecutableElement> overriddenExecutables = _inheritanceManager
1583 .lookupOverrides(_enclosingClass, executableElement.name); 2072 .lookupOverrides(_enclosingClass, executableElement.name);
1584 if (_checkForInstanceMethodNameCollidesWithSuperclassStatic( 2073 if (_checkForInstanceMethodNameCollidesWithSuperclassStatic(
1585 executableElement, errorNameTarget)) { 2074 executableElement, errorNameTarget)) {
1586 return true; 2075 return;
1587 } 2076 }
1588 for (ExecutableElement overriddenElement in overriddenExecutables) { 2077 for (ExecutableElement overriddenElement in overriddenExecutables) {
1589 if (_checkForAllInvalidOverrideErrorCodes(executableElement, 2078 if (_checkForAllInvalidOverrideErrorCodes(executableElement,
1590 overriddenElement, parameters, parameterLocations, errorNameTarget)) { 2079 overriddenElement, parameters, parameterLocations, errorNameTarget)) {
1591 return true; 2080 return;
1592 } 2081 }
1593 } 2082 }
1594 return false;
1595 } 2083 }
1596 2084
1597 /** 2085 /**
1598 * Check the given field [declaration] against override-error codes. 2086 * Check the given field [declaration] against override-error codes.
1599 * 2087 *
1600 * See [_checkForAllInvalidOverrideErrorCodes]. 2088 * See [_checkForAllInvalidOverrideErrorCodes].
1601 */ 2089 */
1602 bool _checkForAllInvalidOverrideErrorCodesForField( 2090 void _checkForAllInvalidOverrideErrorCodesForField(
1603 FieldDeclaration declaration) { 2091 FieldDeclaration declaration) {
2092 if (_options.strongMode) {
2093 return; // strong mode already checked for this
2094 }
2095
1604 if (_enclosingClass == null || declaration.isStatic) { 2096 if (_enclosingClass == null || declaration.isStatic) {
1605 return false; 2097 return;
1606 } 2098 }
1607 bool hasProblems = false; 2099
1608 VariableDeclarationList fields = declaration.fields; 2100 VariableDeclarationList fields = declaration.fields;
1609 for (VariableDeclaration field in fields.variables) { 2101 for (VariableDeclaration field in fields.variables) {
1610 FieldElement element = field.element as FieldElement; 2102 FieldElement element = field.element as FieldElement;
1611 if (element == null) { 2103 if (element == null) {
1612 continue; 2104 continue;
1613 } 2105 }
1614 PropertyAccessorElement getter = element.getter; 2106 PropertyAccessorElement getter = element.getter;
1615 PropertyAccessorElement setter = element.setter; 2107 PropertyAccessorElement setter = element.setter;
1616 SimpleIdentifier fieldName = field.name; 2108 SimpleIdentifier fieldName = field.name;
1617 if (getter != null) { 2109 if (getter != null) {
1618 if (_checkForAllInvalidOverrideErrorCodesForExecutable(getter, 2110 _checkForAllInvalidOverrideErrorCodesForExecutable(
1619 ParameterElement.EMPTY_LIST, AstNode.EMPTY_LIST, fieldName)) { 2111 getter, ParameterElement.EMPTY_LIST, AstNode.EMPTY_LIST, fieldName);
1620 hasProblems = true;
1621 }
1622 } 2112 }
1623 if (setter != null) { 2113 if (setter != null) {
1624 if (_checkForAllInvalidOverrideErrorCodesForExecutable( 2114 _checkForAllInvalidOverrideErrorCodesForExecutable(
1625 setter, setter.parameters, <AstNode>[fieldName], fieldName)) { 2115 setter, setter.parameters, <AstNode>[fieldName], fieldName);
1626 hasProblems = true;
1627 }
1628 } 2116 }
1629 } 2117 }
1630 return hasProblems;
1631 } 2118 }
1632 2119
1633 /** 2120 /**
1634 * Check the given [method] declaration against override-error codes. 2121 * Check the given [method] declaration against override-error codes.
1635 * 2122 *
1636 * See [_checkForAllInvalidOverrideErrorCodes]. 2123 * See [_checkForAllInvalidOverrideErrorCodes].
1637 */ 2124 */
1638 bool _checkForAllInvalidOverrideErrorCodesForMethod( 2125 void _checkForAllInvalidOverrideErrorCodesForMethod(
1639 MethodDeclaration method) { 2126 MethodDeclaration method) {
2127 if (_options.strongMode) {
2128 return; // strong mode already checked for this
2129 }
1640 if (_enclosingClass == null || 2130 if (_enclosingClass == null ||
1641 method.isStatic || 2131 method.isStatic ||
1642 method.body is NativeFunctionBody) { 2132 method.body is NativeFunctionBody) {
1643 return false; 2133 return;
1644 } 2134 }
1645 ExecutableElement executableElement = method.element; 2135 ExecutableElement executableElement = method.element;
1646 if (executableElement == null) { 2136 if (executableElement == null) {
1647 return false; 2137 return;
1648 } 2138 }
1649 SimpleIdentifier methodName = method.name; 2139 SimpleIdentifier methodName = method.name;
1650 if (methodName.isSynthetic) { 2140 if (methodName.isSynthetic) {
1651 return false; 2141 return;
1652 } 2142 }
1653 FormalParameterList formalParameterList = method.parameters; 2143 FormalParameterList formalParameterList = method.parameters;
1654 NodeList<FormalParameter> parameterList = 2144 NodeList<FormalParameter> parameterList = formalParameterList?.parameters;
1655 formalParameterList != null ? formalParameterList.parameters : null;
1656 List<AstNode> parameters = 2145 List<AstNode> parameters =
1657 parameterList != null ? new List.from(parameterList) : null; 2146 parameterList != null ? new List.from(parameterList) : null;
1658 return _checkForAllInvalidOverrideErrorCodesForExecutable(executableElement, 2147 _checkForAllInvalidOverrideErrorCodesForExecutable(executableElement,
1659 executableElement.parameters, parameters, methodName); 2148 executableElement.parameters, parameters, methodName);
1660 } 2149 }
1661 2150
1662 /** 2151 /**
1663 * Verify that all classes of the given [withClause] are valid. 2152 * Verify that all classes of the given [withClause] are valid.
1664 * 2153 *
1665 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR], 2154 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR],
1666 * [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT], and 2155 * [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT], and
1667 * [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]. 2156 * [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER].
1668 */ 2157 */
1669 bool _checkForAllMixinErrorCodes(WithClause withClause) { 2158 bool _checkForAllMixinErrorCodes(WithClause withClause) {
1670 if (withClause == null) { 2159 if (withClause == null) {
1671 return false; 2160 return false;
1672 } 2161 }
1673 bool problemReported = false; 2162 bool problemReported = false;
1674 for (TypeName mixinName in withClause.mixinTypes) { 2163 for (TypeName mixinName in withClause.mixinTypes) {
1675 DartType mixinType = mixinName.type; 2164 DartType mixinType = mixinName.type;
1676 if (mixinType is! InterfaceType) { 2165 if (mixinType is InterfaceType) {
1677 continue; 2166 if (_checkForExtendsOrImplementsDisallowedClass(
1678 } 2167 mixinName, CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS)) {
1679 if (_checkForExtendsOrImplementsDisallowedClass(
1680 mixinName, CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS)) {
1681 problemReported = true;
1682 } else {
1683 ClassElement mixinElement = (mixinType as InterfaceType).element;
1684 if (_checkForExtendsOrImplementsDeferredClass(
1685 mixinName, CompileTimeErrorCode.MIXIN_DEFERRED_CLASS)) {
1686 problemReported = true; 2168 problemReported = true;
1687 } 2169 } else {
1688 if (_checkForMixinDeclaresConstructor(mixinName, mixinElement)) { 2170 ClassElement mixinElement = mixinType.element;
1689 problemReported = true; 2171 if (_checkForExtendsOrImplementsDeferredClass(
1690 } 2172 mixinName, CompileTimeErrorCode.MIXIN_DEFERRED_CLASS)) {
1691 if (!enableSuperMixins && 2173 problemReported = true;
1692 _checkForMixinInheritsNotFromObject(mixinName, mixinElement)) { 2174 }
1693 problemReported = true; 2175 if (_checkForMixinDeclaresConstructor(mixinName, mixinElement)) {
1694 } 2176 problemReported = true;
1695 if (_checkForMixinReferencesSuper(mixinName, mixinElement)) { 2177 }
1696 problemReported = true; 2178 if (!enableSuperMixins &&
2179 _checkForMixinInheritsNotFromObject(mixinName, mixinElement)) {
2180 problemReported = true;
2181 }
2182 if (_checkForMixinReferencesSuper(mixinName, mixinElement)) {
2183 problemReported = true;
2184 }
1697 } 2185 }
1698 } 2186 }
1699 } 2187 }
1700 return problemReported; 2188 return problemReported;
1701 } 2189 }
1702 2190
1703 /** 2191 /**
1704 * Check for errors related to the redirected constructors. 2192 * Check for errors related to the redirected constructors.
1705 * 2193 *
1706 * See [StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE], 2194 * See [StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE],
1707 * [StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE], and 2195 * [StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE], and
1708 * [StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR]. 2196 * [StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR].
1709 */ 2197 */
1710 bool _checkForAllRedirectConstructorErrorCodes( 2198 void _checkForAllRedirectConstructorErrorCodes(
1711 ConstructorDeclaration declaration) { 2199 ConstructorDeclaration declaration) {
1712 //
1713 // Prepare redirected constructor node 2200 // Prepare redirected constructor node
1714 //
1715 ConstructorName redirectedConstructor = declaration.redirectedConstructor; 2201 ConstructorName redirectedConstructor = declaration.redirectedConstructor;
1716 if (redirectedConstructor == null) { 2202 if (redirectedConstructor == null) {
1717 return false; 2203 return;
1718 } 2204 }
1719 // 2205
1720 // Prepare redirected constructor type 2206 // Prepare redirected constructor type
1721 //
1722 ConstructorElement redirectedElement = redirectedConstructor.staticElement; 2207 ConstructorElement redirectedElement = redirectedConstructor.staticElement;
1723 if (redirectedElement == null) { 2208 if (redirectedElement == null) {
1724 //
1725 // If the element is null, we check for the 2209 // If the element is null, we check for the
1726 // REDIRECT_TO_MISSING_CONSTRUCTOR case 2210 // REDIRECT_TO_MISSING_CONSTRUCTOR case
1727 //
1728 TypeName constructorTypeName = redirectedConstructor.type; 2211 TypeName constructorTypeName = redirectedConstructor.type;
1729 DartType redirectedType = constructorTypeName.type; 2212 DartType redirectedType = constructorTypeName.type;
1730 if (redirectedType != null && 2213 if (redirectedType != null &&
1731 redirectedType.element != null && 2214 redirectedType.element != null &&
1732 !redirectedType.isDynamic) { 2215 !redirectedType.isDynamic) {
1733 //
1734 // Prepare the constructor name 2216 // Prepare the constructor name
1735 //
1736 String constructorStrName = constructorTypeName.name.name; 2217 String constructorStrName = constructorTypeName.name.name;
1737 if (redirectedConstructor.name != null) { 2218 if (redirectedConstructor.name != null) {
1738 constructorStrName += ".${redirectedConstructor.name.name}"; 2219 constructorStrName += ".${redirectedConstructor.name.name}";
1739 } 2220 }
1740 ErrorCode errorCode = (declaration.constKeyword != null 2221 ErrorCode errorCode = (declaration.constKeyword != null
1741 ? CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR 2222 ? CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR
1742 : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR); 2223 : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR);
1743 _errorReporter.reportErrorForNode(errorCode, redirectedConstructor, 2224 _errorReporter.reportErrorForNode(errorCode, redirectedConstructor,
1744 [constructorStrName, redirectedType.displayName]); 2225 [constructorStrName, redirectedType.displayName]);
1745 return true;
1746 } 2226 }
1747 return false; 2227 return;
1748 } 2228 }
1749 FunctionType redirectedType = redirectedElement.type; 2229 FunctionType redirectedType = redirectedElement.type;
1750 DartType redirectedReturnType = redirectedType.returnType; 2230 DartType redirectedReturnType = redirectedType.returnType;
1751 // 2231
1752 // Report specific problem when return type is incompatible 2232 // Report specific problem when return type is incompatible
1753 //
1754 FunctionType constructorType = declaration.element.type; 2233 FunctionType constructorType = declaration.element.type;
1755 DartType constructorReturnType = constructorType.returnType; 2234 DartType constructorReturnType = constructorType.returnType;
1756 if (!_typeSystem.isAssignableTo( 2235 if (!_typeSystem.isAssignableTo(
1757 redirectedReturnType, constructorReturnType)) { 2236 redirectedReturnType, constructorReturnType)) {
1758 _errorReporter.reportErrorForNode( 2237 _errorReporter.reportErrorForNode(
1759 StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, 2238 StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE,
1760 redirectedConstructor, 2239 redirectedConstructor,
1761 [redirectedReturnType, constructorReturnType]); 2240 [redirectedReturnType, constructorReturnType]);
1762 return true; 2241 return;
1763 } 2242 } else if (!_typeSystem.isSubtypeOf(redirectedType, constructorType)) {
1764 // 2243 // Check parameters.
1765 // Check parameters
1766 //
1767 if (!_typeSystem.isSubtypeOf(redirectedType, constructorType)) {
1768 _errorReporter.reportErrorForNode( 2244 _errorReporter.reportErrorForNode(
1769 StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE, 2245 StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE,
1770 redirectedConstructor, 2246 redirectedConstructor,
1771 [redirectedType, constructorType]); 2247 [redirectedType, constructorType]);
1772 return true;
1773 } 2248 }
1774 return false;
1775 } 2249 }
1776 2250
1777 /** 2251 /**
1778 * Check that the return [statement] of the form <i>return e;</i> is not in a 2252 * Check that the return [statement] of the form <i>return e;</i> is not in a
1779 * generative constructor. 2253 * generative constructor.
1780 * 2254 *
1781 * Check that return statements without expressions are not in a generative 2255 * Check that return statements without expressions are not in a generative
1782 * constructor and the return type is not assignable to `null`; that is, we 2256 * constructor and the return type is not assignable to `null`; that is, we
1783 * don't have `return;` if the enclosing method has a return type. 2257 * don't have `return;` if the enclosing method has a return type.
1784 * 2258 *
1785 * Check that the return type matches the type of the declared return type in 2259 * Check that the return type matches the type of the declared return type in
1786 * the enclosing method or function. 2260 * the enclosing method or function.
1787 * 2261 *
1788 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR], 2262 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR],
1789 * [StaticWarningCode.RETURN_WITHOUT_VALUE], and 2263 * [StaticWarningCode.RETURN_WITHOUT_VALUE], and
1790 * [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. 2264 * [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE].
1791 */ 2265 */
1792 bool _checkForAllReturnStatementErrorCodes(ReturnStatement statement) { 2266 void _checkForAllReturnStatementErrorCodes(ReturnStatement statement) {
1793 FunctionType functionType = 2267 FunctionType functionType = _enclosingFunction?.type;
1794 _enclosingFunction == null ? null : _enclosingFunction.type;
1795 DartType expectedReturnType = functionType == null 2268 DartType expectedReturnType = functionType == null
1796 ? DynamicTypeImpl.instance 2269 ? DynamicTypeImpl.instance
1797 : functionType.returnType; 2270 : functionType.returnType;
1798 Expression returnExpression = statement.expression; 2271 Expression returnExpression = statement.expression;
1799 // RETURN_IN_GENERATIVE_CONSTRUCTOR 2272 // RETURN_IN_GENERATIVE_CONSTRUCTOR
1800 bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && 2273 bool isGenerativeConstructor(ExecutableElement element) =>
1801 !(_enclosingFunction as ConstructorElement).isFactory; 2274 element is ConstructorElement && !element.isFactory;
1802 if (isGenerativeConstructor) { 2275 if (isGenerativeConstructor(_enclosingFunction)) {
1803 if (returnExpression == null) { 2276 if (returnExpression == null) {
1804 return false; 2277 return;
1805 } 2278 }
1806 _errorReporter.reportErrorForNode( 2279 _errorReporter.reportErrorForNode(
1807 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, 2280 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR,
1808 returnExpression); 2281 returnExpression);
1809 return true; 2282 return;
1810 } 2283 }
1811 // RETURN_WITHOUT_VALUE 2284 // RETURN_WITHOUT_VALUE
1812 if (returnExpression == null) { 2285 if (returnExpression == null) {
1813 if (_inGenerator || 2286 if (_inGenerator ||
1814 _typeSystem.isAssignableTo( 2287 _typeSystem.isAssignableTo(
1815 _computeReturnTypeForMethod(null), expectedReturnType)) { 2288 _computeReturnTypeForMethod(null), expectedReturnType)) {
1816 return false; 2289 return;
1817 } 2290 }
1818 _hasReturnWithoutValue = true; 2291 _hasReturnWithoutValue = true;
1819 _errorReporter.reportErrorForNode( 2292 _errorReporter.reportErrorForNode(
1820 StaticWarningCode.RETURN_WITHOUT_VALUE, statement); 2293 StaticWarningCode.RETURN_WITHOUT_VALUE, statement);
1821 return true; 2294 return;
1822 } else if (_inGenerator) { 2295 } else if (_inGenerator) {
1823 // RETURN_IN_GENERATOR 2296 // RETURN_IN_GENERATOR
1824 _errorReporter.reportErrorForNode( 2297 _errorReporter.reportErrorForNode(
1825 CompileTimeErrorCode.RETURN_IN_GENERATOR, statement); 2298 CompileTimeErrorCode.RETURN_IN_GENERATOR,
2299 statement,
2300 [_inAsync ? "async*" : "sync*"]);
1826 } 2301 }
1827 // RETURN_OF_INVALID_TYPE 2302
1828 return _checkForReturnOfInvalidType(returnExpression, expectedReturnType); 2303 _checkForReturnOfInvalidType(returnExpression, expectedReturnType);
1829 } 2304 }
1830 2305
1831 /** 2306 /**
1832 * Verify that the export namespace of the given export [directive] does not 2307 * Verify that the export namespace of the given export [directive] does not
1833 * export any name already exported by another export directive. The 2308 * export any name already exported by another export directive. The
1834 * [exportElement] is the [ExportElement] retrieved from the node. If the 2309 * [exportElement] is the [ExportElement] retrieved from the node. If the
1835 * element in the node was `null`, then this method is not called. The 2310 * element in the node was `null`, then this method is not called. The
1836 * [exportedLibrary] is the library element containing the exported element. 2311 * [exportedLibrary] is the library element containing the exported element.
1837 * 2312 *
1838 * See [CompileTimeErrorCode.AMBIGUOUS_EXPORT]. 2313 * See [CompileTimeErrorCode.AMBIGUOUS_EXPORT].
1839 */ 2314 */
1840 bool _checkForAmbiguousExport(ExportDirective directive, 2315 void _checkForAmbiguousExport(ExportDirective directive,
1841 ExportElement exportElement, LibraryElement exportedLibrary) { 2316 ExportElement exportElement, LibraryElement exportedLibrary) {
1842 if (exportedLibrary == null) { 2317 if (exportedLibrary == null) {
1843 return false; 2318 return;
1844 } 2319 }
1845 // check exported names 2320 // check exported names
1846 Namespace namespace = 2321 Namespace namespace =
1847 new NamespaceBuilder().createExportNamespaceForDirective(exportElement); 2322 new NamespaceBuilder().createExportNamespaceForDirective(exportElement);
1848 Map<String, Element> definedNames = namespace.definedNames; 2323 Map<String, Element> definedNames = namespace.definedNames;
1849 for (String name in definedNames.keys) { 2324 for (String name in definedNames.keys) {
1850 Element element = definedNames[name]; 2325 Element element = definedNames[name];
1851 Element prevElement = _exportedElements[name]; 2326 Element prevElement = _exportedElements[name];
1852 if (element != null && prevElement != null && prevElement != element) { 2327 if (element != null && prevElement != null && prevElement != element) {
1853 _errorReporter.reportErrorForNode( 2328 _errorReporter.reportErrorForNode(
1854 CompileTimeErrorCode.AMBIGUOUS_EXPORT, directive, [ 2329 CompileTimeErrorCode.AMBIGUOUS_EXPORT, directive, [
1855 name, 2330 name,
1856 prevElement.library.definingCompilationUnit.displayName, 2331 prevElement.library.definingCompilationUnit.displayName,
1857 element.library.definingCompilationUnit.displayName 2332 element.library.definingCompilationUnit.displayName
1858 ]); 2333 ]);
1859 return true; 2334 return;
1860 } else { 2335 } else {
1861 _exportedElements[name] = element; 2336 _exportedElements[name] = element;
1862 } 2337 }
1863 } 2338 }
1864 return false;
1865 } 2339 }
1866 2340
1867 /** 2341 /**
2342 * Check the given node to see whether it was ambiguous because the name was
2343 * imported from two or more imports.
2344 */
2345 void _checkForAmbiguousImport(SimpleIdentifier node) {
2346 Element element = node.staticElement;
2347 if (element is MultiplyDefinedElementImpl) {
2348 String name = element.displayName;
2349 List<Element> conflictingMembers = element.conflictingElements;
2350 int count = conflictingMembers.length;
2351 List<String> libraryNames = new List<String>(count);
2352 for (int i = 0; i < count; i++) {
2353 libraryNames[i] = _getLibraryName(conflictingMembers[i]);
2354 }
2355 libraryNames.sort();
2356 _errorReporter.reportErrorForNode(StaticWarningCode.AMBIGUOUS_IMPORT,
2357 node, [name, StringUtilities.printListOfQuotedNames(libraryNames)]);
2358 } else {
2359 List<Element> sdkElements =
2360 node.getProperty(LibraryImportScope.conflictingSdkElements);
2361 if (sdkElements != null) {
2362 _errorReporter.reportErrorForNode(
2363 StaticWarningCode.CONFLICTING_DART_IMPORT, node, [
2364 element.displayName,
2365 _getLibraryName(sdkElements[0]),
2366 _getLibraryName(element)
2367 ]);
2368 }
2369 }
2370 }
2371
2372 /**
1868 * Verify that the given [expression] can be assigned to its corresponding 2373 * Verify that the given [expression] can be assigned to its corresponding
1869 * parameters. The [expectedStaticType] is the expected static type of the 2374 * parameters. The [expectedStaticType] is the expected static type of the
1870 * parameter. The [actualStaticType] is the actual static type of the 2375 * parameter. The [actualStaticType] is the actual static type of the
1871 * argument. 2376 * argument.
1872 * 2377 *
1873 * This method corresponds to 2378 * This method corresponds to
1874 * [BestPracticesVerifier.checkForArgumentTypeNotAssignable]. 2379 * [BestPracticesVerifier.checkForArgumentTypeNotAssignable].
1875 * 2380 *
1876 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], 2381 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE],
1877 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], 2382 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
1878 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], 2383 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
1879 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], 2384 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE],
1880 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], 2385 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE],
1881 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and 2386 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and
1882 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. 2387 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE].
1883 */ 2388 */
1884 bool _checkForArgumentTypeNotAssignable( 2389 void _checkForArgumentTypeNotAssignable(
1885 Expression expression, 2390 Expression expression,
1886 DartType expectedStaticType, 2391 DartType expectedStaticType,
1887 DartType actualStaticType, 2392 DartType actualStaticType,
1888 ErrorCode errorCode) { 2393 ErrorCode errorCode) {
1889 //
1890 // Warning case: test static type information 2394 // Warning case: test static type information
1891 //
1892 if (actualStaticType != null && expectedStaticType != null) { 2395 if (actualStaticType != null && expectedStaticType != null) {
1893 if (!_typeSystem.isAssignableTo(actualStaticType, expectedStaticType)) { 2396 _checkForAssignableExpressionAtType(
1894 _errorReporter.reportTypeErrorForNode( 2397 expression, actualStaticType, expectedStaticType, errorCode);
1895 errorCode, expression, [actualStaticType, expectedStaticType]);
1896 return true;
1897 }
1898 } 2398 }
1899 return false;
1900 } 2399 }
1901 2400
1902 /** 2401 /**
1903 * Verify that the given [argument] can be assigned to its corresponding 2402 * Verify that the given [argument] can be assigned to its corresponding
1904 * parameter. 2403 * parameter.
1905 * 2404 *
1906 * This method corresponds to 2405 * This method corresponds to
1907 * [BestPracticesVerifier.checkForArgumentTypeNotAssignableForArgument]. 2406 * [BestPracticesVerifier.checkForArgumentTypeNotAssignableForArgument].
1908 * 2407 *
1909 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. 2408 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
1910 */ 2409 */
1911 bool _checkForArgumentTypeNotAssignableForArgument(Expression argument) { 2410 void _checkForArgumentTypeNotAssignableForArgument(Expression argument) {
1912 if (argument == null) { 2411 if (argument == null) {
1913 return false; 2412 return;
1914 } 2413 }
1915 ParameterElement staticParameterElement = argument.staticParameterElement; 2414 ParameterElement staticParameterElement = argument.staticParameterElement;
1916 DartType staticParameterType = 2415 DartType staticParameterType = staticParameterElement?.type;
1917 staticParameterElement == null ? null : staticParameterElement.type; 2416 _checkForArgumentTypeNotAssignableWithExpectedTypes(argument,
1918 return _checkForArgumentTypeNotAssignableWithExpectedTypes(argument,
1919 staticParameterType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); 2417 staticParameterType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
1920 } 2418 }
1921 2419
1922 /** 2420 /**
1923 * Verify that the given [expression] can be assigned to its corresponding 2421 * Verify that the given [expression] can be assigned to its corresponding
1924 * parameters. The [expectedStaticType] is the expected static type. 2422 * parameters. The [expectedStaticType] is the expected static type.
1925 * 2423 *
1926 * This method corresponds to 2424 * This method corresponds to
1927 * [BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes]. 2425 * [BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes].
1928 * 2426 *
1929 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], 2427 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE],
1930 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], 2428 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
1931 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], 2429 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
1932 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], 2430 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE],
1933 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], 2431 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE],
1934 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and 2432 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and
1935 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. 2433 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE].
1936 */ 2434 */
1937 bool _checkForArgumentTypeNotAssignableWithExpectedTypes( 2435 void _checkForArgumentTypeNotAssignableWithExpectedTypes(
1938 Expression expression, 2436 Expression expression, DartType expectedStaticType, ErrorCode errorCode) {
1939 DartType expectedStaticType, 2437 _checkForArgumentTypeNotAssignable(
1940 ErrorCode errorCode) => 2438 expression, expectedStaticType, getStaticType(expression), errorCode);
1941 _checkForArgumentTypeNotAssignable( 2439 }
1942 expression, expectedStaticType, getStaticType(expression), errorCode);
1943 2440
1944 /** 2441 /**
1945 * Verify that the arguments in the given [argumentList] can be assigned to 2442 * Verify that the arguments in the given [argumentList] can be assigned to
1946 * their corresponding parameters. 2443 * their corresponding parameters.
1947 * 2444 *
1948 * This method corresponds to 2445 * This method corresponds to
1949 * [BestPracticesVerifier.checkForArgumentTypesNotAssignableInList]. 2446 * [BestPracticesVerifier.checkForArgumentTypesNotAssignableInList].
1950 * 2447 *
1951 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. 2448 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
1952 */ 2449 */
1953 bool _checkForArgumentTypesNotAssignableInList(ArgumentList argumentList) { 2450 void _checkForArgumentTypesNotAssignableInList(ArgumentList argumentList) {
1954 if (argumentList == null) { 2451 if (argumentList == null) {
1955 return false; 2452 return;
1956 } 2453 }
1957 bool problemReported = false; 2454
1958 for (Expression argument in argumentList.arguments) { 2455 for (Expression argument in argumentList.arguments) {
1959 if (_checkForArgumentTypeNotAssignableForArgument(argument)) { 2456 _checkForArgumentTypeNotAssignableForArgument(argument);
1960 problemReported = true;
1961 }
1962 } 2457 }
1963 return problemReported;
1964 } 2458 }
1965 2459
1966 /** 2460 /**
1967 * Check that the static type of the given expression is assignable to the 2461 * Check that the static type of the given expression is assignable to the
1968 * given type. If it isn't, report an error with the given error code. The 2462 * given type. If it isn't, report an error with the given error code. The
1969 * [type] is the type that the expression must be assignable to. The 2463 * [type] is the type that the expression must be assignable to. The
1970 * [errorCode] is the error code to be reported. The [arguments] are the 2464 * [errorCode] is the error code to be reported. The [arguments] are the
1971 * arguments to pass in when creating the error. 2465 * arguments to pass in when creating the error.
1972 */ 2466 */
1973 bool _checkForAssignability(Expression expression, InterfaceType type, 2467 void _checkForAssignability(Expression expression, InterfaceType type,
1974 ErrorCode errorCode, List<Object> arguments) { 2468 ErrorCode errorCode, List<Object> arguments) {
1975 if (expression == null) { 2469 if (expression == null) {
1976 return false; 2470 return;
1977 } 2471 }
1978 DartType expressionType = expression.staticType; 2472 DartType expressionType = expression.staticType;
1979 if (expressionType == null) { 2473 if (expressionType == null) {
2474 return;
2475 }
2476 if (_expressionIsAssignableAtType(expression, expressionType, type)) {
2477 return;
2478 }
2479 _errorReporter.reportErrorForNode(errorCode, expression, arguments);
2480 }
2481
2482 bool _checkForAssignableExpression(
2483 Expression expression, DartType expectedStaticType, ErrorCode errorCode) {
2484 DartType actualStaticType = getStaticType(expression);
2485 return actualStaticType != null &&
2486 _checkForAssignableExpressionAtType(
2487 expression, actualStaticType, expectedStaticType, errorCode);
2488 }
2489
2490 bool _checkForAssignableExpressionAtType(
2491 Expression expression,
2492 DartType actualStaticType,
2493 DartType expectedStaticType,
2494 ErrorCode errorCode) {
2495 // TODO(leafp): Move the Downcast functionality here.
2496 if (!_expressionIsAssignableAtType(
2497 expression, actualStaticType, expectedStaticType)) {
2498 _errorReporter.reportTypeErrorForNode(
2499 errorCode, expression, [actualStaticType, expectedStaticType]);
1980 return false; 2500 return false;
1981 } 2501 }
1982 if (_typeSystem.isAssignableTo(expressionType, type)) {
1983 return false;
1984 }
1985 _errorReporter.reportErrorForNode(errorCode, expression, arguments);
1986 return true; 2502 return true;
1987 } 2503 }
1988 2504
1989 /** 2505 /**
1990 * Verify that the given [expression] is not final. 2506 * Verify that the given [expression] is not final.
1991 * 2507 *
1992 * See [StaticWarningCode.ASSIGNMENT_TO_CONST], 2508 * See [StaticWarningCode.ASSIGNMENT_TO_CONST],
1993 * [StaticWarningCode.ASSIGNMENT_TO_FINAL], and 2509 * [StaticWarningCode.ASSIGNMENT_TO_FINAL], and
1994 * [StaticWarningCode.ASSIGNMENT_TO_METHOD]. 2510 * [StaticWarningCode.ASSIGNMENT_TO_METHOD].
1995 */ 2511 */
1996 bool _checkForAssignmentToFinal(Expression expression) { 2512 void _checkForAssignmentToFinal(Expression expression) {
1997 // prepare element 2513 // prepare element
1998 Element element = null; 2514 Element element = null;
1999 AstNode highlightedNode = expression; 2515 AstNode highlightedNode = expression;
2000 if (expression is Identifier) { 2516 if (expression is Identifier) {
2001 element = expression.staticElement; 2517 element = expression.staticElement;
2002 if (expression is PrefixedIdentifier) { 2518 if (expression is PrefixedIdentifier) {
2003 highlightedNode = expression.identifier; 2519 highlightedNode = expression.identifier;
2004 } 2520 }
2005 } else if (expression is PropertyAccess) { 2521 } else if (expression is PropertyAccess) {
2006 PropertyAccess propertyAccess = expression; 2522 element = expression.propertyName.staticElement;
2007 element = propertyAccess.propertyName.staticElement; 2523 highlightedNode = expression.propertyName;
2008 highlightedNode = propertyAccess.propertyName;
2009 } 2524 }
2010 // check if element is assignable 2525 // check if element is assignable
2011 if (element is PropertyAccessorElement) { 2526 Element toVariable(Element element) {
2012 PropertyAccessorElement accessor = element as PropertyAccessorElement; 2527 return element is PropertyAccessorElement ? element.variable : element;
2013 element = accessor.variable;
2014 } 2528 }
2529
2530 element = toVariable(element);
2015 if (element is VariableElement) { 2531 if (element is VariableElement) {
2016 if (element.isConst) { 2532 if (element.isConst) {
2017 _errorReporter.reportErrorForNode( 2533 _errorReporter.reportErrorForNode(
2018 StaticWarningCode.ASSIGNMENT_TO_CONST, expression); 2534 StaticWarningCode.ASSIGNMENT_TO_CONST, expression);
2019 return true; 2535 } else if (element.isFinal) {
2020 }
2021 if (element.isFinal) {
2022 if (element is FieldElementImpl && 2536 if (element is FieldElementImpl &&
2023 element.setter == null && 2537 element.setter == null &&
2024 element.isSynthetic) { 2538 element.isSynthetic) {
2025 _errorReporter.reportErrorForNode( 2539 _errorReporter.reportErrorForNode(
2026 StaticWarningCode.ASSIGNMENT_TO_FINAL_NO_SETTER, 2540 StaticWarningCode.ASSIGNMENT_TO_FINAL_NO_SETTER,
2027 highlightedNode, 2541 highlightedNode,
2028 [element.name, element.enclosingElement.displayName]); 2542 [element.name, element.enclosingElement.displayName]);
2029 return true; 2543 return;
2030 } 2544 }
2031 _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_FINAL, 2545 _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_FINAL,
2032 highlightedNode, [element.name]); 2546 highlightedNode, [element.name]);
2033 return true;
2034 } 2547 }
2035 return false; 2548 } else if (element is FunctionElement) {
2036 }
2037 if (element is FunctionElement) {
2038 _errorReporter.reportErrorForNode( 2549 _errorReporter.reportErrorForNode(
2039 StaticWarningCode.ASSIGNMENT_TO_FUNCTION, expression); 2550 StaticWarningCode.ASSIGNMENT_TO_FUNCTION, expression);
2040 return true; 2551 } else if (element is MethodElement) {
2041 }
2042 if (element is MethodElement) {
2043 _errorReporter.reportErrorForNode( 2552 _errorReporter.reportErrorForNode(
2044 StaticWarningCode.ASSIGNMENT_TO_METHOD, expression); 2553 StaticWarningCode.ASSIGNMENT_TO_METHOD, expression);
2045 return true; 2554 } else if (element is ClassElement ||
2046 }
2047 if (element is ClassElement ||
2048 element is FunctionTypeAliasElement || 2555 element is FunctionTypeAliasElement ||
2049 element is TypeParameterElement) { 2556 element is TypeParameterElement) {
2050 _errorReporter.reportErrorForNode( 2557 _errorReporter.reportErrorForNode(
2051 StaticWarningCode.ASSIGNMENT_TO_TYPE, expression); 2558 StaticWarningCode.ASSIGNMENT_TO_TYPE, expression);
2052 return true;
2053 } 2559 }
2054 return false;
2055 } 2560 }
2056 2561
2057 /** 2562 /**
2058 * Verify that the given [identifier] is not a keyword, and generates the 2563 * Verify that the given [identifier] is not a keyword, and generates the
2059 * given [errorCode] on the identifier if it is a keyword. 2564 * given [errorCode] on the identifier if it is a keyword.
2060 * 2565 *
2061 * See [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME], 2566 * See [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME],
2062 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME], and 2567 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME], and
2063 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]. 2568 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME].
2064 */ 2569 */
2065 bool _checkForBuiltInIdentifierAsName( 2570 void _checkForBuiltInIdentifierAsName(
2066 SimpleIdentifier identifier, ErrorCode errorCode) { 2571 SimpleIdentifier identifier, ErrorCode errorCode) {
2067 sc.Token token = identifier.token; 2572 Token token = identifier.token;
2068 if (token.type == sc.TokenType.KEYWORD) { 2573 if (token.type == TokenType.KEYWORD) {
2069 _errorReporter.reportErrorForNode( 2574 _errorReporter
2070 errorCode, identifier, [identifier.name]); 2575 .reportErrorForNode(errorCode, identifier, [identifier.name]);
2071 return true;
2072 } 2576 }
2073 return false;
2074 } 2577 }
2075 2578
2076 /** 2579 /**
2077 * Verify that the given [switchCase] is terminated with 'break', 'continue', 2580 * Verify that the given [switchCase] is terminated with 'break', 'continue',
2078 * 'return' or 'throw'. 2581 * 'return' or 'throw'.
2079 * 2582 *
2080 * see [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]. 2583 * see [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED].
2081 */ 2584 */
2082 bool _checkForCaseBlockNotTerminated(SwitchCase switchCase) { 2585 void _checkForCaseBlockNotTerminated(SwitchCase switchCase) {
2083 NodeList<Statement> statements = switchCase.statements; 2586 NodeList<Statement> statements = switchCase.statements;
2084 if (statements.isEmpty) { 2587 if (statements.isEmpty) {
2085 // fall-through without statements at all 2588 // fall-through without statements at all
2086 AstNode parent = switchCase.parent; 2589 AstNode parent = switchCase.parent;
2087 if (parent is SwitchStatement) { 2590 if (parent is SwitchStatement) {
2088 SwitchStatement switchStatement = parent; 2591 NodeList<SwitchMember> members = parent.members;
2089 NodeList<SwitchMember> members = switchStatement.members;
2090 int index = members.indexOf(switchCase); 2592 int index = members.indexOf(switchCase);
2091 if (index != -1 && index < members.length - 1) { 2593 if (index != -1 && index < members.length - 1) {
2092 return false; 2594 return;
2093 } 2595 }
2094 } 2596 }
2095 // no other switch member after this one 2597 // no other switch member after this one
2096 } else { 2598 } else {
2097 Statement statement = statements[statements.length - 1]; 2599 Statement statement = statements[statements.length - 1];
2098 // terminated with statement 2600 // terminated with statement
2099 if (statement is BreakStatement || 2601 if (statement is BreakStatement ||
2100 statement is ContinueStatement || 2602 statement is ContinueStatement ||
2101 statement is ReturnStatement) { 2603 statement is ReturnStatement) {
2102 return false; 2604 return;
2103 } 2605 }
2104 // terminated with 'throw' expression 2606 // terminated with 'throw' expression
2105 if (statement is ExpressionStatement) { 2607 if (statement is ExpressionStatement) {
2106 Expression expression = statement.expression; 2608 Expression expression = statement.expression;
2107 if (expression is ThrowExpression) { 2609 if (expression is ThrowExpression) {
2108 return false; 2610 return;
2109 } 2611 }
2110 } 2612 }
2111 } 2613 }
2112 // report error 2614
2113 _errorReporter.reportErrorForToken( 2615 _errorReporter.reportErrorForToken(
2114 StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, switchCase.keyword); 2616 StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, switchCase.keyword);
2115 return true;
2116 } 2617 }
2117 2618
2118 /** 2619 /**
2119 * Verify that the switch cases in the given switch [statement] are terminated 2620 * Verify that the switch cases in the given switch [statement] are terminated
2120 * with 'break', 'continue', 'return' or 'throw'. 2621 * with 'break', 'continue', 'return' or 'throw'.
2121 * 2622 *
2122 * See [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]. 2623 * See [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED].
2123 */ 2624 */
2124 bool _checkForCaseBlocksNotTerminated(SwitchStatement statement) { 2625 void _checkForCaseBlocksNotTerminated(SwitchStatement statement) {
2125 bool foundError = false;
2126 NodeList<SwitchMember> members = statement.members; 2626 NodeList<SwitchMember> members = statement.members;
2127 int lastMember = members.length - 1; 2627 int lastMember = members.length - 1;
2128 for (int i = 0; i < lastMember; i++) { 2628 for (int i = 0; i < lastMember; i++) {
2129 SwitchMember member = members[i]; 2629 SwitchMember member = members[i];
2130 if (member is SwitchCase && _checkForCaseBlockNotTerminated(member)) { 2630 if (member is SwitchCase) {
2131 foundError = true; 2631 _checkForCaseBlockNotTerminated(member);
2132 } 2632 }
2133 } 2633 }
2134 return foundError;
2135 } 2634 }
2136 2635
2137 /** 2636 /**
2138 * Verify that the given [method] declaration is abstract only if the 2637 * Verify that the given [method] declaration is abstract only if the
2139 * enclosing class is also abstract. 2638 * enclosing class is also abstract.
2140 * 2639 *
2141 * See [StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER]. 2640 * See [StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER].
2142 */ 2641 */
2143 bool _checkForConcreteClassWithAbstractMember(MethodDeclaration method) { 2642 void _checkForConcreteClassWithAbstractMember(MethodDeclaration method) {
2144 if (method.isAbstract && 2643 if (method.isAbstract &&
2145 _enclosingClass != null && 2644 _enclosingClass != null &&
2146 !_enclosingClass.isAbstract) { 2645 !_enclosingClass.isAbstract) {
2147 SimpleIdentifier nameNode = method.name; 2646 SimpleIdentifier nameNode = method.name;
2148 String memberName = nameNode.name; 2647 String memberName = nameNode.name;
2149 ExecutableElement overriddenMember; 2648 ExecutableElement overriddenMember;
2150 if (method.isGetter) { 2649 if (method.isGetter) {
2151 overriddenMember = _enclosingClass.lookUpInheritedConcreteGetter( 2650 overriddenMember = _enclosingClass.lookUpInheritedConcreteGetter(
2152 memberName, _currentLibrary); 2651 memberName, _currentLibrary);
2153 } else if (method.isSetter) { 2652 } else if (method.isSetter) {
2154 overriddenMember = _enclosingClass.lookUpInheritedConcreteSetter( 2653 overriddenMember = _enclosingClass.lookUpInheritedConcreteSetter(
2155 memberName, _currentLibrary); 2654 memberName, _currentLibrary);
2156 } else { 2655 } else {
2157 overriddenMember = _enclosingClass.lookUpInheritedConcreteMethod( 2656 overriddenMember = _enclosingClass.lookUpInheritedConcreteMethod(
2158 memberName, _currentLibrary); 2657 memberName, _currentLibrary);
2159 } 2658 }
2160 if (overriddenMember == null) { 2659 if (overriddenMember == null && !_enclosingClass.hasNoSuchMethod) {
2161 _errorReporter.reportErrorForNode( 2660 _errorReporter.reportErrorForNode(
2162 StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, 2661 StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER,
2163 nameNode, 2662 nameNode,
2164 [memberName, _enclosingClass.displayName]); 2663 [memberName, _enclosingClass.displayName]);
2165 return true;
2166 } 2664 }
2167 } 2665 }
2168 return false;
2169 } 2666 }
2170 2667
2171 /** 2668 /**
2172 * Verify all possible conflicts of the given [constructor]'s name with other 2669 * Verify all possible conflicts of the given [constructor]'s name with other
2173 * constructors and members of the same class. The [constructorElement] is the 2670 * constructors and members of the same class. The [constructorElement] is the
2174 * constructor's element. 2671 * constructor's element.
2175 * 2672 *
2176 * See [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT], 2673 * See [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT],
2177 * [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME], 2674 * [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME],
2178 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD], and 2675 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD], and
2179 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD]. 2676 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD].
2180 */ 2677 */
2181 bool _checkForConflictingConstructorNameAndMember( 2678 void _checkForConflictingConstructorNameAndMember(
2182 ConstructorDeclaration constructor, 2679 ConstructorDeclaration constructor,
2183 ConstructorElement constructorElement) { 2680 ConstructorElement constructorElement) {
2184 SimpleIdentifier constructorName = constructor.name; 2681 SimpleIdentifier constructorName = constructor.name;
2185 String name = constructorElement.name; 2682 String name = constructorElement.name;
2186 ClassElement classElement = constructorElement.enclosingElement; 2683 ClassElement classElement = constructorElement.enclosingElement;
2187 // constructors 2684 // constructors
2188 List<ConstructorElement> constructors = classElement.constructors; 2685 List<ConstructorElement> constructors = classElement.constructors;
2189 for (ConstructorElement otherConstructor in constructors) { 2686 for (ConstructorElement otherConstructor in constructors) {
2190 if (identical(otherConstructor, constructorElement)) { 2687 if (identical(otherConstructor, constructorElement)) {
2191 continue; 2688 continue;
2192 } 2689 }
2193 if (name == otherConstructor.name) { 2690 if (name == otherConstructor.name) {
2194 if (name == null || name.length == 0) { 2691 if (name == null || name.length == 0) {
2195 _errorReporter.reportErrorForNode( 2692 _errorReporter.reportErrorForNode(
2196 CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, constructor); 2693 CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, constructor);
2197 } else { 2694 } else {
2198 _errorReporter.reportErrorForNode( 2695 _errorReporter.reportErrorForNode(
2199 CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME, 2696 CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
2200 constructor, 2697 constructor,
2201 [name]); 2698 [name]);
2202 } 2699 }
2203 return true; 2700 return;
2204 } 2701 }
2205 } 2702 }
2206 // conflict with class member 2703 // conflict with class member
2207 if (constructorName != null && 2704 if (constructorName != null &&
2208 constructorElement != null && 2705 constructorElement != null &&
2209 !constructorName.isSynthetic) { 2706 !constructorName.isSynthetic) {
2210 // fields 2707 if (classElement.getField(name) != null) {
2211 FieldElement field = classElement.getField(name); 2708 // fields
2212 if (field != null) {
2213 _errorReporter.reportErrorForNode( 2709 _errorReporter.reportErrorForNode(
2214 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, 2710 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD,
2215 constructor, 2711 constructor,
2216 [name]); 2712 [name]);
2217 return true; 2713 } else if (classElement.getMethod(name) != null) {
2218 } 2714 // methods
2219 // methods
2220 MethodElement method = classElement.getMethod(name);
2221 if (method != null) {
2222 _errorReporter.reportErrorForNode( 2715 _errorReporter.reportErrorForNode(
2223 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, 2716 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD,
2224 constructor, 2717 constructor,
2225 [name]); 2718 [name]);
2226 return true;
2227 } 2719 }
2228 } 2720 }
2229 return false;
2230 } 2721 }
2231 2722
2232 /** 2723 /**
2233 * Verify that the [_enclosingClass] does not have a method and getter pair 2724 * Verify that the [_enclosingClass] does not have a method and getter pair
2234 * with the same name on, via inheritance. 2725 * with the same name on, via inheritance.
2235 * 2726 *
2236 * See [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD], and 2727 * See [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD], and
2237 * [CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER]. 2728 * [CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER].
2238 */ 2729 */
2239 bool _checkForConflictingGetterAndMethod() { 2730 void _checkForConflictingGetterAndMethod() {
2240 if (_enclosingClass == null) { 2731 if (_enclosingClass == null) {
2241 return false; 2732 return;
2242 } 2733 }
2243 bool hasProblem = false; 2734
2244 // method declared in the enclosing class vs. inherited getter 2735 // method declared in the enclosing class vs. inherited getter
2245 for (MethodElement method in _enclosingClass.methods) { 2736 for (MethodElement method in _enclosingClass.methods) {
2246 String name = method.name; 2737 String name = method.name;
2247 // find inherited property accessor (and can be only getter) 2738 // find inherited property accessor (and can be only getter)
2248 ExecutableElement inherited = 2739 ExecutableElement inherited =
2249 _inheritanceManager.lookupInheritance(_enclosingClass, name); 2740 _inheritanceManager.lookupInheritance(_enclosingClass, name);
2250 if (inherited is! PropertyAccessorElement) { 2741 if (inherited is! PropertyAccessorElement) {
2251 continue; 2742 continue;
2252 } 2743 }
2253 // report problem 2744
2254 hasProblem = true;
2255 _errorReporter.reportErrorForElement( 2745 _errorReporter.reportErrorForElement(
2256 CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD, method, [ 2746 CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD, method, [
2257 _enclosingClass.displayName, 2747 _enclosingClass.displayName,
2258 inherited.enclosingElement.displayName, 2748 inherited.enclosingElement.displayName,
2259 name 2749 name
2260 ]); 2750 ]);
2261 } 2751 }
2262 // getter declared in the enclosing class vs. inherited method 2752 // getter declared in the enclosing class vs. inherited method
2263 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { 2753 for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
2264 if (!accessor.isGetter) { 2754 if (!accessor.isGetter) {
2265 continue; 2755 continue;
2266 } 2756 }
2267 String name = accessor.name; 2757 String name = accessor.name;
2268 // find inherited method 2758 // find inherited method
2269 ExecutableElement inherited = 2759 ExecutableElement inherited =
2270 _inheritanceManager.lookupInheritance(_enclosingClass, name); 2760 _inheritanceManager.lookupInheritance(_enclosingClass, name);
2271 if (inherited is! MethodElement) { 2761 if (inherited is! MethodElement) {
2272 continue; 2762 continue;
2273 } 2763 }
2274 // report problem 2764
2275 hasProblem = true;
2276 _errorReporter.reportErrorForElement( 2765 _errorReporter.reportErrorForElement(
2277 CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER, accessor, [ 2766 CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER, accessor, [
2278 _enclosingClass.displayName, 2767 _enclosingClass.displayName,
2279 inherited.enclosingElement.displayName, 2768 inherited.enclosingElement.displayName,
2280 name 2769 name
2281 ]); 2770 ]);
2282 } 2771 }
2283 // done
2284 return hasProblem;
2285 } 2772 }
2286 2773
2287 /** 2774 /**
2288 * Verify that the superclass of the [_enclosingClass] does not declare 2775 * Verify that the superclass of the [_enclosingClass] does not declare
2289 * accessible static members with the same name as the instance 2776 * accessible static members with the same name as the instance
2290 * getters/setters declared in [_enclosingClass]. 2777 * getters/setters declared in [_enclosingClass].
2291 * 2778 *
2292 * See [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER], and 2779 * See [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER], and
2293 * [StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER]. 2780 * [StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER].
2294 */ 2781 */
2295 bool _checkForConflictingInstanceGetterAndSuperclassMember() { 2782 void _checkForConflictingInstanceGetterAndSuperclassMember() {
2296 if (_enclosingClass == null) { 2783 if (_enclosingClass == null) {
2297 return false; 2784 return;
2298 } 2785 }
2299 InterfaceType enclosingType = _enclosingClass.type; 2786 InterfaceType enclosingType = _enclosingClass.type;
2300 // check every accessor 2787 // check every accessor
2301 bool hasProblem = false;
2302 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { 2788 for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
2303 // we analyze instance accessors here 2789 // we analyze instance accessors here
2304 if (accessor.isStatic) { 2790 if (accessor.isStatic) {
2305 continue; 2791 continue;
2306 } 2792 }
2307 // prepare accessor properties 2793 // prepare accessor properties
2308 String name = accessor.displayName; 2794 String name = accessor.displayName;
2309 bool getter = accessor.isGetter; 2795 bool getter = accessor.isGetter;
2310 // if non-final variable, ignore setter - we alreay reported problem for 2796 // if non-final variable, ignore setter - we alreay reported problem for
2311 // getter 2797 // getter
(...skipping 16 matching lines...) Expand all
2328 continue; 2814 continue;
2329 } 2815 }
2330 // OK, not static 2816 // OK, not static
2331 if (!superElement.isStatic) { 2817 if (!superElement.isStatic) {
2332 continue; 2818 continue;
2333 } 2819 }
2334 // prepare "super" type to report its name 2820 // prepare "super" type to report its name
2335 ClassElement superElementClass = 2821 ClassElement superElementClass =
2336 superElement.enclosingElement as ClassElement; 2822 superElement.enclosingElement as ClassElement;
2337 InterfaceType superElementType = superElementClass.type; 2823 InterfaceType superElementType = superElementClass.type;
2338 // report problem 2824
2339 hasProblem = true;
2340 if (getter) { 2825 if (getter) {
2341 _errorReporter.reportErrorForElement( 2826 _errorReporter.reportErrorForElement(
2342 StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, 2827 StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER,
2343 accessor, 2828 accessor,
2344 [superElementType.displayName]); 2829 [superElementType.displayName]);
2345 } else { 2830 } else {
2346 _errorReporter.reportErrorForElement( 2831 _errorReporter.reportErrorForElement(
2347 StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, 2832 StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER,
2348 accessor, 2833 accessor,
2349 [superElementType.displayName]); 2834 [superElementType.displayName]);
2350 } 2835 }
2351 } 2836 }
2352 // done
2353 return hasProblem;
2354 } 2837 }
2355 2838
2356 /** 2839 /**
2357 * Verify that the enclosing class does not have a setter with the same name 2840 * Verify that the enclosing class does not have a setter with the same name
2358 * as the given instance method declaration. 2841 * as the given instance method declaration.
2359 * 2842 *
2360 * TODO(jwren) add other "conflicting" error codes into algorithm/ data 2843 * TODO(jwren) add other "conflicting" error codes into algorithm/ data
2361 * structure. 2844 * structure.
2362 * 2845 *
2363 * See [StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER]. 2846 * See [StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER].
2364 */ 2847 */
2365 bool _checkForConflictingInstanceMethodSetter(ClassDeclaration declaration) { 2848 void _checkForConflictingInstanceMethodSetter(ClassDeclaration declaration) {
2366 // Reference all of the class members in this class. 2849 // Reference all of the class members in this class.
2367 NodeList<ClassMember> classMembers = declaration.members; 2850 NodeList<ClassMember> classMembers = declaration.members;
2368 if (classMembers.isEmpty) { 2851 if (classMembers.isEmpty) {
2369 return false; 2852 return;
2370 } 2853 }
2371 // Create a HashMap to track conflicting members, and then loop through 2854 // Create a HashMap to track conflicting members, and then loop through
2372 // members in the class to construct the HashMap, at the same time, 2855 // members in the class to construct the HashMap, at the same time,
2373 // look for violations. Don't add members if they are part of a conflict, 2856 // look for violations. Don't add members if they are part of a conflict,
2374 // this prevents multiple warnings for one issue. 2857 // this prevents multiple warnings for one issue.
2375 bool foundError = false;
2376 HashMap<String, ClassMember> memberHashMap = 2858 HashMap<String, ClassMember> memberHashMap =
2377 new HashMap<String, ClassMember>(); 2859 new HashMap<String, ClassMember>();
2378 for (ClassMember classMember in classMembers) { 2860 for (ClassMember member in classMembers) {
2379 if (classMember is MethodDeclaration) { 2861 if (member is MethodDeclaration) {
2380 MethodDeclaration method = classMember; 2862 if (member.isStatic) {
2381 if (method.isStatic) {
2382 continue; 2863 continue;
2383 } 2864 }
2384 // prepare name 2865 // prepare name
2385 SimpleIdentifier name = method.name; 2866 SimpleIdentifier name = member.name;
2386 if (name == null) { 2867 if (name == null) {
2387 continue; 2868 continue;
2388 } 2869 }
2389 bool addThisMemberToTheMap = true; 2870 bool addThisMemberToTheMap = true;
2390 bool isGetter = method.isGetter; 2871 bool isGetter = member.isGetter;
2391 bool isSetter = method.isSetter; 2872 bool isSetter = member.isSetter;
2392 bool isOperator = method.isOperator; 2873 bool isOperator = member.isOperator;
2393 bool isMethod = !isGetter && !isSetter && !isOperator; 2874 bool isMethod = !isGetter && !isSetter && !isOperator;
2394 // Do lookups in the enclosing class (and the inherited member) if the 2875 // Do lookups in the enclosing class (and the inherited member) if the
2395 // member is a method or a setter for 2876 // member is a method or a setter for
2396 // StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER warning. 2877 // StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER warning.
2397 if (isMethod) { 2878 if (isMethod) {
2398 String setterName = "${name.name}="; 2879 String setterName = "${name.name}=";
2399 Element enclosingElementOfSetter = null; 2880 Element enclosingElementOfSetter = null;
2400 ClassMember conflictingSetter = memberHashMap[setterName]; 2881 ClassMember conflictingSetter = memberHashMap[setterName];
2401 if (conflictingSetter != null) { 2882 if (conflictingSetter != null) {
2402 enclosingElementOfSetter = 2883 enclosingElementOfSetter =
2403 conflictingSetter.element.enclosingElement; 2884 conflictingSetter.element.enclosingElement;
2404 } else { 2885 } else {
2405 ExecutableElement elementFromInheritance = _inheritanceManager 2886 ExecutableElement elementFromInheritance = _inheritanceManager
2406 .lookupInheritance(_enclosingClass, setterName); 2887 .lookupInheritance(_enclosingClass, setterName);
2407 if (elementFromInheritance != null) { 2888 if (elementFromInheritance != null) {
2408 enclosingElementOfSetter = 2889 enclosingElementOfSetter =
2409 elementFromInheritance.enclosingElement; 2890 elementFromInheritance.enclosingElement;
2410 } 2891 }
2411 } 2892 }
2412 if (enclosingElementOfSetter != null) { 2893 if (enclosingElementOfSetter != null) {
2413 // report problem
2414 _errorReporter.reportErrorForNode( 2894 _errorReporter.reportErrorForNode(
2415 StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER, name, [ 2895 StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER, name, [
2416 _enclosingClass.displayName, 2896 _enclosingClass.displayName,
2417 name.name, 2897 name.name,
2418 enclosingElementOfSetter.displayName 2898 enclosingElementOfSetter.displayName
2419 ]); 2899 ]);
2420 foundError = true;
2421 addThisMemberToTheMap = false; 2900 addThisMemberToTheMap = false;
2422 } 2901 }
2423 } else if (isSetter) { 2902 } else if (isSetter) {
2424 String methodName = name.name; 2903 String methodName = name.name;
2425 ClassMember conflictingMethod = memberHashMap[methodName]; 2904 ClassMember conflictingMethod = memberHashMap[methodName];
2426 if (conflictingMethod != null && 2905 if (conflictingMethod != null &&
2427 conflictingMethod is MethodDeclaration && 2906 conflictingMethod is MethodDeclaration &&
2428 !conflictingMethod.isGetter) { 2907 !conflictingMethod.isGetter) {
2429 // report problem
2430 _errorReporter.reportErrorForNode( 2908 _errorReporter.reportErrorForNode(
2431 StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2, 2909 StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2,
2432 name, 2910 name,
2433 [_enclosingClass.displayName, name.name]); 2911 [_enclosingClass.displayName, name.name]);
2434 foundError = true;
2435 addThisMemberToTheMap = false; 2912 addThisMemberToTheMap = false;
2436 } 2913 }
2437 } 2914 }
2438 // Finally, add this member into the HashMap. 2915 // Finally, add this member into the HashMap.
2439 if (addThisMemberToTheMap) { 2916 if (addThisMemberToTheMap) {
2440 if (method.isSetter) { 2917 if (member.isSetter) {
2441 memberHashMap["${name.name}="] = method; 2918 memberHashMap["${name.name}="] = member;
2442 } else { 2919 } else {
2443 memberHashMap[name.name] = method; 2920 memberHashMap[name.name] = member;
2444 } 2921 }
2445 } 2922 }
2446 } 2923 }
2447 } 2924 }
2448 return foundError;
2449 } 2925 }
2450 2926
2451 /** 2927 /**
2452 * Verify that the enclosing class does not have an instance member with the 2928 * Verify that the enclosing class does not have an instance member with the
2453 * same name as the given static [method] declaration. 2929 * same name as the given static [method] declaration.
2454 * 2930 *
2455 * See [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]. 2931 * See [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER].
2456 */ 2932 */
2457 bool _checkForConflictingStaticGetterAndInstanceSetter( 2933 void _checkForConflictingStaticGetterAndInstanceSetter(
2458 MethodDeclaration method) { 2934 MethodDeclaration method) {
2459 if (!method.isStatic) { 2935 if (!method.isStatic) {
2460 return false; 2936 return;
2461 } 2937 }
2462 // prepare name 2938 // prepare name
2463 SimpleIdentifier nameNode = method.name; 2939 SimpleIdentifier nameNode = method.name;
2464 if (nameNode == null) { 2940 if (nameNode == null) {
2465 return false; 2941 return;
2466 } 2942 }
2467 String name = nameNode.name; 2943 String name = nameNode.name;
2468 // prepare enclosing type 2944 // prepare enclosing type
2469 if (_enclosingClass == null) { 2945 if (_enclosingClass == null) {
2470 return false; 2946 return;
2471 } 2947 }
2472 InterfaceType enclosingType = _enclosingClass.type; 2948 InterfaceType enclosingType = _enclosingClass.type;
2473 // try to find setter 2949 // try to find setter
2474 ExecutableElement setter = 2950 ExecutableElement setter =
2475 enclosingType.lookUpSetter(name, _currentLibrary); 2951 enclosingType.lookUpSetter(name, _currentLibrary);
2476 if (setter == null) { 2952 if (setter == null) {
2477 return false; 2953 return;
2478 } 2954 }
2479 // OK, also static 2955 // OK, also static
2480 if (setter.isStatic) { 2956 if (setter.isStatic) {
2481 return false; 2957 return;
2482 } 2958 }
2483 // prepare "setter" type to report its name 2959 // prepare "setter" type to report its name
2484 ClassElement setterClass = setter.enclosingElement as ClassElement; 2960 ClassElement setterClass = setter.enclosingElement as ClassElement;
2485 InterfaceType setterType = setterClass.type; 2961 InterfaceType setterType = setterClass.type;
2486 // report problem 2962
2487 _errorReporter.reportErrorForNode( 2963 _errorReporter.reportErrorForNode(
2488 StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER, 2964 StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER,
2489 nameNode, 2965 nameNode,
2490 [setterType.displayName]); 2966 [setterType.displayName]);
2491 return true;
2492 } 2967 }
2493 2968
2494 /** 2969 /**
2495 * Verify that the enclosing class does not have an instance member with the 2970 * Verify that the enclosing class does not have an instance member with the
2496 * same name as the given static [method] declaration. 2971 * same name as the given static [method] declaration.
2497 * 2972 *
2498 * See [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]. 2973 * See [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER].
2499 */ 2974 */
2500 bool _checkForConflictingStaticSetterAndInstanceMember( 2975 void _checkForConflictingStaticSetterAndInstanceMember(
2501 MethodDeclaration method) { 2976 MethodDeclaration method) {
2502 if (!method.isStatic) { 2977 if (!method.isStatic) {
2503 return false; 2978 return;
2504 } 2979 }
2505 // prepare name 2980 // prepare name
2506 SimpleIdentifier nameNode = method.name; 2981 SimpleIdentifier nameNode = method.name;
2507 if (nameNode == null) { 2982 if (nameNode == null) {
2508 return false; 2983 return;
2509 } 2984 }
2510 String name = nameNode.name; 2985 String name = nameNode.name;
2511 // prepare enclosing type 2986 // prepare enclosing type
2512 if (_enclosingClass == null) { 2987 if (_enclosingClass == null) {
2513 return false; 2988 return;
2514 } 2989 }
2515 InterfaceType enclosingType = _enclosingClass.type; 2990 InterfaceType enclosingType = _enclosingClass.type;
2516 // try to find member 2991 // try to find member
2517 ExecutableElement member; 2992 ExecutableElement member;
2518 member = enclosingType.lookUpMethod(name, _currentLibrary); 2993 member = enclosingType.lookUpMethod(name, _currentLibrary);
2519 if (member == null) { 2994 if (member == null) {
2520 member = enclosingType.lookUpGetter(name, _currentLibrary); 2995 member = enclosingType.lookUpGetter(name, _currentLibrary);
2521 } 2996 }
2522 if (member == null) { 2997 if (member == null) {
2523 member = enclosingType.lookUpSetter(name, _currentLibrary); 2998 member = enclosingType.lookUpSetter(name, _currentLibrary);
2524 } 2999 }
2525 if (member == null) { 3000 if (member == null) {
2526 return false; 3001 return;
2527 } 3002 }
2528 // OK, also static 3003 // OK, also static
2529 if (member.isStatic) { 3004 if (member.isStatic) {
2530 return false; 3005 return;
2531 } 3006 }
2532 // prepare "member" type to report its name 3007 // prepare "member" type to report its name
2533 ClassElement memberClass = member.enclosingElement as ClassElement; 3008 ClassElement memberClass = member.enclosingElement as ClassElement;
2534 InterfaceType memberType = memberClass.type; 3009 InterfaceType memberType = memberClass.type;
2535 // report problem 3010
2536 _errorReporter.reportErrorForNode( 3011 _errorReporter.reportErrorForNode(
2537 StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER, 3012 StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER,
2538 nameNode, 3013 nameNode,
2539 [memberType.displayName]); 3014 [memberType.displayName]);
2540 return true;
2541 } 3015 }
2542 3016
2543 /** 3017 /**
2544 * Verify all conflicts between type variable and enclosing class. 3018 * Verify all conflicts between type variable and enclosing class.
2545 * TODO(scheglov) 3019 * TODO(scheglov)
2546 * 3020 *
2547 * See [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS], and 3021 * See [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS], and
2548 * [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]. 3022 * [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER].
2549 */ 3023 */
2550 bool _checkForConflictingTypeVariableErrorCodes( 3024 void _checkForConflictingTypeVariableErrorCodes(
2551 ClassDeclaration declaration) { 3025 ClassDeclaration declaration) {
2552 bool problemReported = false;
2553 for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) { 3026 for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) {
2554 String name = typeParameter.name; 3027 String name = typeParameter.name;
2555 // name is same as the name of the enclosing class 3028 // name is same as the name of the enclosing class
2556 if (_enclosingClass.name == name) { 3029 if (_enclosingClass.name == name) {
2557 _errorReporter.reportErrorForElement( 3030 _errorReporter.reportErrorForElement(
2558 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, 3031 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS,
2559 typeParameter, 3032 typeParameter,
2560 [name]); 3033 [name]);
2561 problemReported = true;
2562 } 3034 }
2563 // check members 3035 // check members
2564 if (_enclosingClass.getMethod(name) != null || 3036 if (_enclosingClass.getMethod(name) != null ||
2565 _enclosingClass.getGetter(name) != null || 3037 _enclosingClass.getGetter(name) != null ||
2566 _enclosingClass.getSetter(name) != null) { 3038 _enclosingClass.getSetter(name) != null) {
2567 _errorReporter.reportErrorForElement( 3039 _errorReporter.reportErrorForElement(
2568 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER, 3040 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER,
2569 typeParameter, 3041 typeParameter,
2570 [name]); 3042 [name]);
2571 problemReported = true;
2572 } 3043 }
2573 } 3044 }
2574 return problemReported;
2575 } 3045 }
2576 3046
2577 /** 3047 /**
2578 * Verify that if the given [constructor] declaration is 'const' then there 3048 * Verify that if the given [constructor] declaration is 'const' then there
2579 * are no invocations of non-'const' super constructors. 3049 * are no invocations of non-'const' super constructors.
2580 * 3050 *
2581 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]. 3051 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER].
2582 */ 3052 */
2583 bool _checkForConstConstructorWithNonConstSuper( 3053 void _checkForConstConstructorWithNonConstSuper(
2584 ConstructorDeclaration constructor) { 3054 ConstructorDeclaration constructor) {
2585 if (!_isEnclosingConstructorConst) { 3055 if (!_isEnclosingConstructorConst) {
2586 return false; 3056 return;
2587 } 3057 }
2588 // OK, const factory, checked elsewhere 3058 // OK, const factory, checked elsewhere
2589 if (constructor.factoryKeyword != null) { 3059 if (constructor.factoryKeyword != null) {
2590 return false; 3060 return;
2591 } 3061 }
2592 // check for mixins 3062 // check for mixins
2593 if (_enclosingClass.mixins.length != 0) { 3063 if (_enclosingClass.mixins.length != 0) {
2594 _errorReporter.reportErrorForNode( 3064 _errorReporter.reportErrorForNode(
2595 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN, 3065 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN,
2596 constructor.returnType); 3066 constructor.returnType);
2597 return true; 3067 return;
2598 } 3068 }
2599 // try to find and check super constructor invocation 3069 // try to find and check super constructor invocation
2600 for (ConstructorInitializer initializer in constructor.initializers) { 3070 for (ConstructorInitializer initializer in constructor.initializers) {
2601 if (initializer is SuperConstructorInvocation) { 3071 if (initializer is SuperConstructorInvocation) {
2602 SuperConstructorInvocation superInvocation = initializer; 3072 ConstructorElement element = initializer.staticElement;
2603 ConstructorElement element = superInvocation.staticElement;
2604 if (element == null || element.isConst) { 3073 if (element == null || element.isConst) {
2605 return false; 3074 return;
2606 } 3075 }
2607 _errorReporter.reportErrorForNode( 3076 _errorReporter.reportErrorForNode(
2608 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, 3077 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER,
2609 superInvocation, 3078 initializer,
2610 [element.enclosingElement.displayName]); 3079 [element.enclosingElement.displayName]);
2611 return true; 3080 return;
2612 } 3081 }
2613 } 3082 }
2614 // no explicit super constructor invocation, check default constructor 3083 // no explicit super constructor invocation, check default constructor
2615 InterfaceType supertype = _enclosingClass.supertype; 3084 InterfaceType supertype = _enclosingClass.supertype;
2616 if (supertype == null) { 3085 if (supertype == null) {
2617 return false; 3086 return;
2618 } 3087 }
2619 if (supertype.isObject) { 3088 if (supertype.isObject) {
2620 return false; 3089 return;
2621 } 3090 }
2622 ConstructorElement unnamedConstructor = 3091 ConstructorElement unnamedConstructor =
2623 supertype.element.unnamedConstructor; 3092 supertype.element.unnamedConstructor;
2624 if (unnamedConstructor == null) { 3093 if (unnamedConstructor == null || unnamedConstructor.isConst) {
2625 return false; 3094 return;
2626 } 3095 }
2627 if (unnamedConstructor.isConst) { 3096
2628 return false;
2629 }
2630 // default constructor is not 'const', report problem 3097 // default constructor is not 'const', report problem
2631 _errorReporter.reportErrorForNode( 3098 _errorReporter.reportErrorForNode(
2632 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, 3099 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER,
2633 constructor.returnType, 3100 constructor.returnType,
2634 [supertype.displayName]); 3101 [supertype.displayName]);
2635 return true;
2636 } 3102 }
2637 3103
2638 /** 3104 /**
2639 * Verify that if the given [constructor] declaration is 'const' then there 3105 * Verify that if the given [constructor] declaration is 'const' then there
2640 * are no non-final instance variable. The [constructorElement] is the 3106 * are no non-final instance variable. The [constructorElement] is the
2641 * constructor element. 3107 * constructor element.
2642 * 3108 *
2643 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]. 3109 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD].
2644 */ 3110 */
2645 bool _checkForConstConstructorWithNonFinalField( 3111 void _checkForConstConstructorWithNonFinalField(
2646 ConstructorDeclaration constructor, 3112 ConstructorDeclaration constructor,
2647 ConstructorElement constructorElement) { 3113 ConstructorElement constructorElement) {
2648 if (!_isEnclosingConstructorConst) { 3114 if (!_isEnclosingConstructorConst) {
2649 return false; 3115 return;
2650 } 3116 }
2651 // check if there is non-final field 3117 // check if there is non-final field
2652 ClassElement classElement = constructorElement.enclosingElement; 3118 ClassElement classElement = constructorElement.enclosingElement;
2653 if (!classElement.hasNonFinalField) { 3119 if (!classElement.hasNonFinalField) {
2654 return false; 3120 return;
2655 } 3121 }
2656 // report problem 3122
2657 _errorReporter.reportErrorForNode( 3123 _errorReporter.reportErrorForNode(
2658 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, 3124 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
2659 constructor); 3125 constructor);
2660 return true;
2661 } 3126 }
2662 3127
2663 /** 3128 /**
2664 * Verify that the given 'const' instance creation [expression] is not 3129 * Verify that the given 'const' instance creation [expression] is not
2665 * creating a deferred type. The [constructorName] is the constructor name, 3130 * creating a deferred type. The [constructorName] is the constructor name,
2666 * always non-`null`. The [typeName] is the name of the type defining the 3131 * always non-`null`. The [typeName] is the name of the type defining the
2667 * constructor, always non-`null`. 3132 * constructor, always non-`null`.
2668 * 3133 *
2669 * See [CompileTimeErrorCode.CONST_DEFERRED_CLASS]. 3134 * See [CompileTimeErrorCode.CONST_DEFERRED_CLASS].
2670 */ 3135 */
2671 bool _checkForConstDeferredClass(InstanceCreationExpression expression, 3136 void _checkForConstDeferredClass(InstanceCreationExpression expression,
2672 ConstructorName constructorName, TypeName typeName) { 3137 ConstructorName constructorName, TypeName typeName) {
2673 if (typeName.isDeferred) { 3138 if (typeName.isDeferred) {
2674 _errorReporter.reportErrorForNode( 3139 _errorReporter.reportErrorForNode(
2675 CompileTimeErrorCode.CONST_DEFERRED_CLASS, 3140 CompileTimeErrorCode.CONST_DEFERRED_CLASS,
2676 constructorName, 3141 constructorName,
2677 [typeName.name.name]); 3142 [typeName.name.name]);
2678 return true;
2679 } 3143 }
2680 return false;
2681 } 3144 }
2682 3145
2683 /** 3146 /**
2684 * Verify that the given throw [expression] is not enclosed in a 'const' 3147 * Verify that the given throw [expression] is not enclosed in a 'const'
2685 * constructor declaration. 3148 * constructor declaration.
2686 * 3149 *
2687 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION]. 3150 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION].
2688 */ 3151 */
2689 bool _checkForConstEvalThrowsException(ThrowExpression expression) { 3152 void _checkForConstEvalThrowsException(ThrowExpression expression) {
2690 if (_isEnclosingConstructorConst) { 3153 if (_isEnclosingConstructorConst) {
2691 _errorReporter.reportErrorForNode( 3154 _errorReporter.reportErrorForNode(
2692 CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, expression); 3155 CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, expression);
2693 return true;
2694 } 3156 }
2695 return false;
2696 } 3157 }
2697 3158
2698 /** 3159 /**
2699 * Verify that the given normal formal [parameter] is not 'const'. 3160 * Verify that the given normal formal [parameter] is not 'const'.
2700 * 3161 *
2701 * See [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]. 3162 * See [CompileTimeErrorCode.CONST_FORMAL_PARAMETER].
2702 */ 3163 */
2703 bool _checkForConstFormalParameter(NormalFormalParameter parameter) { 3164 void _checkForConstFormalParameter(NormalFormalParameter parameter) {
2704 if (parameter.isConst) { 3165 if (parameter.isConst) {
2705 _errorReporter.reportErrorForNode( 3166 _errorReporter.reportErrorForNode(
2706 CompileTimeErrorCode.CONST_FORMAL_PARAMETER, parameter); 3167 CompileTimeErrorCode.CONST_FORMAL_PARAMETER, parameter);
2707 return true;
2708 } 3168 }
2709 return false;
2710 } 3169 }
2711 3170
2712 /** 3171 /**
2713 * Verify that the given instance creation [expression] is not being invoked 3172 * Verify that the given instance creation [expression] is not being invoked
2714 * on an abstract class. The [typeName] is the [TypeName] of the 3173 * on an abstract class. The [typeName] is the [TypeName] of the
2715 * [ConstructorName] from the [InstanceCreationExpression], this is the AST 3174 * [ConstructorName] from the [InstanceCreationExpression], this is the AST
2716 * node that the error is attached to. The [type] is the type being 3175 * node that the error is attached to. The [type] is the type being
2717 * constructed with this [InstanceCreationExpression]. 3176 * constructed with this [InstanceCreationExpression].
2718 * 3177 *
2719 * See [StaticWarningCode.CONST_WITH_ABSTRACT_CLASS], and 3178 * See [StaticWarningCode.CONST_WITH_ABSTRACT_CLASS], and
2720 * [StaticWarningCode.NEW_WITH_ABSTRACT_CLASS]. 3179 * [StaticWarningCode.NEW_WITH_ABSTRACT_CLASS].
2721 */ 3180 */
2722 bool _checkForConstOrNewWithAbstractClass( 3181 void _checkForConstOrNewWithAbstractClass(
2723 InstanceCreationExpression expression, 3182 InstanceCreationExpression expression,
2724 TypeName typeName, 3183 TypeName typeName,
2725 InterfaceType type) { 3184 InterfaceType type) {
2726 if (type.element.isAbstract) { 3185 if (type.element.isAbstract) {
2727 ConstructorElement element = expression.staticElement; 3186 ConstructorElement element = expression.staticElement;
2728 if (element != null && !element.isFactory) { 3187 if (element != null && !element.isFactory) {
2729 if ((expression.keyword as sc.KeywordToken).keyword == 3188 if (expression.keyword.keyword == Keyword.CONST) {
2730 sc.Keyword.CONST) {
2731 _errorReporter.reportErrorForNode( 3189 _errorReporter.reportErrorForNode(
2732 StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName); 3190 StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName);
2733 } else { 3191 } else {
2734 _errorReporter.reportErrorForNode( 3192 _errorReporter.reportErrorForNode(
2735 StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName); 3193 StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName);
2736 } 3194 }
2737 return true;
2738 } 3195 }
2739 } 3196 }
2740 return false;
2741 } 3197 }
2742 3198
2743 /** 3199 /**
2744 * Verify that the given instance creation [expression] is not being invoked 3200 * Verify that the given instance creation [expression] is not being invoked
2745 * on an enum. The [typeName] is the [TypeName] of the [ConstructorName] from 3201 * on an enum. The [typeName] is the [TypeName] of the [ConstructorName] from
2746 * the [InstanceCreationExpression], this is the AST node that the error is 3202 * the [InstanceCreationExpression], this is the AST node that the error is
2747 * attached to. The [type] is the type being constructed with this 3203 * attached to. The [type] is the type being constructed with this
2748 * [InstanceCreationExpression]. 3204 * [InstanceCreationExpression].
2749 * 3205 *
2750 * See [CompileTimeErrorCode.INSTANTIATE_ENUM]. 3206 * See [CompileTimeErrorCode.INSTANTIATE_ENUM].
2751 */ 3207 */
2752 bool _checkForConstOrNewWithEnum(InstanceCreationExpression expression, 3208 void _checkForConstOrNewWithEnum(InstanceCreationExpression expression,
2753 TypeName typeName, InterfaceType type) { 3209 TypeName typeName, InterfaceType type) {
2754 if (type.element.isEnum) { 3210 if (type.element.isEnum) {
2755 _errorReporter.reportErrorForNode( 3211 _errorReporter.reportErrorForNode(
2756 CompileTimeErrorCode.INSTANTIATE_ENUM, typeName); 3212 CompileTimeErrorCode.INSTANTIATE_ENUM, typeName);
2757 return true;
2758 } 3213 }
2759 return false;
2760 } 3214 }
2761 3215
2762 /** 3216 /**
2763 * Verify that the given 'const' instance creation [expression] is not being 3217 * Verify that the given 'const' instance creation [expression] is not being
2764 * invoked on a constructor that is not 'const'. 3218 * invoked on a constructor that is not 'const'.
2765 * 3219 *
2766 * This method assumes that the instance creation was tested to be 'const' 3220 * This method assumes that the instance creation was tested to be 'const'
2767 * before being called. 3221 * before being called.
2768 * 3222 *
2769 * See [CompileTimeErrorCode.CONST_WITH_NON_CONST]. 3223 * See [CompileTimeErrorCode.CONST_WITH_NON_CONST].
2770 */ 3224 */
2771 bool _checkForConstWithNonConst(InstanceCreationExpression expression) { 3225 void _checkForConstWithNonConst(InstanceCreationExpression expression) {
2772 ConstructorElement constructorElement = expression.staticElement; 3226 ConstructorElement constructorElement = expression.staticElement;
2773 if (constructorElement != null && !constructorElement.isConst) { 3227 if (constructorElement != null && !constructorElement.isConst) {
2774 _errorReporter.reportErrorForNode( 3228 _errorReporter.reportErrorForNode(
2775 CompileTimeErrorCode.CONST_WITH_NON_CONST, expression); 3229 CompileTimeErrorCode.CONST_WITH_NON_CONST, expression);
2776 return true;
2777 } 3230 }
2778 return false;
2779 } 3231 }
2780 3232
2781 /** 3233 /**
2782 * Verify that the given [typeName] does not reference any type parameters. 3234 * Verify that the given [typeName] does not reference any type parameters.
2783 * 3235 *
2784 * See [CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS]. 3236 * See [CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS].
2785 */ 3237 */
2786 bool _checkForConstWithTypeParameters(TypeName typeName) { 3238 void _checkForConstWithTypeParameters(TypeName typeName) {
2787 // something wrong with AST 3239 // something wrong with AST
2788 if (typeName == null) { 3240 if (typeName == null) {
2789 return false; 3241 return;
2790 } 3242 }
2791 Identifier name = typeName.name; 3243 Identifier name = typeName.name;
2792 if (name == null) { 3244 if (name == null) {
2793 return false; 3245 return;
2794 } 3246 }
2795 // should not be a type parameter 3247 // should not be a type parameter
2796 if (name.staticElement is TypeParameterElement) { 3248 if (name.staticElement is TypeParameterElement) {
2797 _errorReporter.reportErrorForNode( 3249 _errorReporter.reportErrorForNode(
2798 CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, name); 3250 CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, name);
2799 } 3251 }
2800 // check type arguments 3252 // check type arguments
2801 TypeArgumentList typeArguments = typeName.typeArguments; 3253 TypeArgumentList typeArguments = typeName.typeArguments;
2802 if (typeArguments != null) { 3254 if (typeArguments != null) {
2803 bool hasError = false;
2804 for (TypeName argument in typeArguments.arguments) { 3255 for (TypeName argument in typeArguments.arguments) {
2805 if (_checkForConstWithTypeParameters(argument)) { 3256 _checkForConstWithTypeParameters(argument);
2806 hasError = true;
2807 }
2808 } 3257 }
2809 return hasError;
2810 } 3258 }
2811 // OK
2812 return false;
2813 } 3259 }
2814 3260
2815 /** 3261 /**
2816 * Verify that if the given 'const' instance creation [expression] is being 3262 * Verify that if the given 'const' instance creation [expression] is being
2817 * invoked on the resolved constructor. The [constructorName] is the 3263 * invoked on the resolved constructor. The [constructorName] is the
2818 * constructor name, always non-`null`. The [typeName] is the name of the type 3264 * constructor name, always non-`null`. The [typeName] is the name of the type
2819 * defining the constructor, always non-`null`. 3265 * defining the constructor, always non-`null`.
2820 * 3266 *
2821 * This method assumes that the instance creation was tested to be 'const' 3267 * This method assumes that the instance creation was tested to be 'const'
2822 * before being called. 3268 * before being called.
2823 * 3269 *
2824 * See [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR], and 3270 * See [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR], and
2825 * [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]. 3271 * [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT].
2826 */ 3272 */
2827 bool _checkForConstWithUndefinedConstructor( 3273 void _checkForConstWithUndefinedConstructor(
2828 InstanceCreationExpression expression, 3274 InstanceCreationExpression expression,
2829 ConstructorName constructorName, 3275 ConstructorName constructorName,
2830 TypeName typeName) { 3276 TypeName typeName) {
2831 // OK if resolved 3277 // OK if resolved
2832 if (expression.staticElement != null) { 3278 if (expression.staticElement != null) {
2833 return false; 3279 return;
2834 } 3280 }
2835 DartType type = typeName.type; 3281 DartType type = typeName.type;
2836 if (type is InterfaceType) { 3282 if (type is InterfaceType) {
2837 ClassElement element = type.element; 3283 ClassElement element = type.element;
2838 if (element != null && element.isEnum) { 3284 if (element != null && element.isEnum) {
2839 // We have already reported the error. 3285 // We have already reported the error.
2840 return false; 3286 return;
2841 } 3287 }
2842 } 3288 }
2843 Identifier className = typeName.name; 3289 Identifier className = typeName.name;
2844 // report as named or default constructor absence 3290 // report as named or default constructor absence
2845 SimpleIdentifier name = constructorName.name; 3291 SimpleIdentifier name = constructorName.name;
2846 if (name != null) { 3292 if (name != null) {
2847 _errorReporter.reportErrorForNode( 3293 _errorReporter.reportErrorForNode(
2848 CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR, 3294 CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR,
2849 name, 3295 name,
2850 [className, name]); 3296 [className, name]);
2851 } else { 3297 } else {
2852 _errorReporter.reportErrorForNode( 3298 _errorReporter.reportErrorForNode(
2853 CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, 3299 CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
2854 constructorName, 3300 constructorName,
2855 [className]); 3301 [className]);
2856 } 3302 }
2857 return true;
2858 } 3303 }
2859 3304
2860 /** 3305 /**
2861 * Verify that there are no default parameters in the given function type 3306 * Verify that there are no default parameters in the given function type
2862 * [alias]. 3307 * [alias].
2863 * 3308 *
2864 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]. 3309 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS].
2865 */ 3310 */
2866 bool _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias alias) { 3311 void _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias alias) {
2867 bool result = false;
2868 FormalParameterList formalParameterList = alias.parameters; 3312 FormalParameterList formalParameterList = alias.parameters;
2869 NodeList<FormalParameter> parameters = formalParameterList.parameters; 3313 NodeList<FormalParameter> parameters = formalParameterList.parameters;
2870 for (FormalParameter formalParameter in parameters) { 3314 for (FormalParameter parameter in parameters) {
2871 if (formalParameter is DefaultFormalParameter) { 3315 if (parameter is DefaultFormalParameter) {
2872 DefaultFormalParameter defaultFormalParameter = formalParameter; 3316 if (parameter.defaultValue != null) {
2873 if (defaultFormalParameter.defaultValue != null) {
2874 _errorReporter.reportErrorForNode( 3317 _errorReporter.reportErrorForNode(
2875 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, alias); 3318 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, alias);
2876 result = true;
2877 } 3319 }
2878 } 3320 }
2879 } 3321 }
2880 return result;
2881 } 3322 }
2882 3323
2883 /** 3324 /**
2884 * Verify that the given default formal [parameter] is not part of a function 3325 * Verify that the given default formal [parameter] is not part of a function
2885 * typed parameter. 3326 * typed parameter.
2886 * 3327 *
2887 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]. 3328 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER].
2888 */ 3329 */
2889 bool _checkForDefaultValueInFunctionTypedParameter( 3330 void _checkForDefaultValueInFunctionTypedParameter(
2890 DefaultFormalParameter parameter) { 3331 DefaultFormalParameter parameter) {
2891 // OK, not in a function typed parameter. 3332 // OK, not in a function typed parameter.
2892 if (!_isInFunctionTypedFormalParameter) { 3333 if (!_isInFunctionTypedFormalParameter) {
2893 return false; 3334 return;
2894 } 3335 }
2895 // OK, no default value. 3336 // OK, no default value.
2896 if (parameter.defaultValue == null) { 3337 if (parameter.defaultValue == null) {
2897 return false; 3338 return;
2898 } 3339 }
2899 // Report problem. 3340
2900 _errorReporter.reportErrorForNode( 3341 _errorReporter.reportErrorForNode(
2901 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, 3342 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
2902 parameter); 3343 parameter);
2903 return true;
2904 } 3344 }
2905 3345
2906 /** 3346 /**
2907 * Verify that any deferred imports in the given compilation [unit] have a 3347 * Verify that any deferred imports in the given compilation [unit] have a
2908 * unique prefix. 3348 * unique prefix.
2909 * 3349 *
2910 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. 3350 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX].
2911 */ 3351 */
2912 bool _checkForDeferredPrefixCollisions(CompilationUnit unit) { 3352 void _checkForDeferredPrefixCollisions(CompilationUnit unit) {
2913 bool foundError = false;
2914 NodeList<Directive> directives = unit.directives; 3353 NodeList<Directive> directives = unit.directives;
2915 int count = directives.length; 3354 int count = directives.length;
2916 if (count > 0) { 3355 if (count > 0) {
2917 HashMap<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = 3356 HashMap<PrefixElement, List<ImportDirective>> prefixToDirectivesMap =
2918 new HashMap<PrefixElement, List<ImportDirective>>(); 3357 new HashMap<PrefixElement, List<ImportDirective>>();
2919 for (int i = 0; i < count; i++) { 3358 for (int i = 0; i < count; i++) {
2920 Directive directive = directives[i]; 3359 Directive directive = directives[i];
2921 if (directive is ImportDirective) { 3360 if (directive is ImportDirective) {
2922 ImportDirective importDirective = directive; 3361 SimpleIdentifier prefix = directive.prefix;
2923 SimpleIdentifier prefix = importDirective.prefix;
2924 if (prefix != null) { 3362 if (prefix != null) {
2925 Element element = prefix.staticElement; 3363 Element element = prefix.staticElement;
2926 if (element is PrefixElement) { 3364 if (element is PrefixElement) {
2927 PrefixElement prefixElement = element; 3365 List<ImportDirective> elements = prefixToDirectivesMap[element];
2928 List<ImportDirective> elements =
2929 prefixToDirectivesMap[prefixElement];
2930 if (elements == null) { 3366 if (elements == null) {
2931 elements = new List<ImportDirective>(); 3367 elements = new List<ImportDirective>();
2932 prefixToDirectivesMap[prefixElement] = elements; 3368 prefixToDirectivesMap[element] = elements;
2933 } 3369 }
2934 elements.add(importDirective); 3370 elements.add(directive);
2935 } 3371 }
2936 } 3372 }
2937 } 3373 }
2938 } 3374 }
2939 for (List<ImportDirective> imports in prefixToDirectivesMap.values) { 3375 for (List<ImportDirective> imports in prefixToDirectivesMap.values) {
2940 if (_hasDeferredPrefixCollision(imports)) { 3376 _checkDeferredPrefixCollision(imports);
2941 foundError = true;
2942 }
2943 } 3377 }
2944 } 3378 }
2945 return foundError;
2946 } 3379 }
2947 3380
2948 /** 3381 /**
2949 * Verify that the enclosing class does not have an instance member with the 3382 * Verify that the enclosing class does not have an instance member with the
2950 * given name of the static member. 3383 * given name of the static member.
2951 * 3384 *
2952 * See [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]. 3385 * See [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE].
2953 */ 3386 */
2954 bool _checkForDuplicateDefinitionInheritance() { 3387 void _checkForDuplicateDefinitionInheritance() {
2955 if (_enclosingClass == null) { 3388 if (_enclosingClass == null) {
2956 return false; 3389 return;
2957 } 3390 }
2958 bool hasProblem = false; 3391
2959 for (ExecutableElement member in _enclosingClass.methods) { 3392 for (ExecutableElement member in _enclosingClass.methods) {
2960 if (member.isStatic && _checkForDuplicateDefinitionOfMember(member)) { 3393 if (member.isStatic) {
2961 hasProblem = true; 3394 _checkForDuplicateDefinitionOfMember(member);
2962 } 3395 }
2963 } 3396 }
2964 for (ExecutableElement member in _enclosingClass.accessors) { 3397 for (ExecutableElement member in _enclosingClass.accessors) {
2965 if (member.isStatic && _checkForDuplicateDefinitionOfMember(member)) { 3398 if (member.isStatic) {
2966 hasProblem = true; 3399 _checkForDuplicateDefinitionOfMember(member);
2967 } 3400 }
2968 } 3401 }
2969 return hasProblem;
2970 } 3402 }
2971 3403
2972 /** 3404 /**
2973 * Verify that the enclosing class does not have an instance member with the 3405 * Verify that the enclosing class does not have an instance member with the
2974 * given name of the [staticMember]. 3406 * given name of the [staticMember].
2975 * 3407 *
2976 * See [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]. 3408 * See [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE].
2977 */ 3409 */
2978 bool _checkForDuplicateDefinitionOfMember(ExecutableElement staticMember) { 3410 void _checkForDuplicateDefinitionOfMember(ExecutableElement staticMember) {
2979 // prepare name 3411 // prepare name
2980 String name = staticMember.name; 3412 String name = staticMember.name;
2981 if (name == null) { 3413 if (name == null) {
2982 return false; 3414 return;
2983 } 3415 }
2984 // try to find member 3416 // try to find member
2985 ExecutableElement inheritedMember = 3417 ExecutableElement inheritedMember =
2986 _inheritanceManager.lookupInheritance(_enclosingClass, name); 3418 _inheritanceManager.lookupInheritance(_enclosingClass, name);
2987 if (inheritedMember == null) { 3419 if (inheritedMember == null) {
2988 return false; 3420 return;
2989 } 3421 }
2990 // OK, also static 3422 // OK, also static
2991 if (inheritedMember.isStatic) { 3423 if (inheritedMember.isStatic) {
2992 return false; 3424 return;
2993 } 3425 }
2994 // determine the display name, use the extended display name if the 3426 // determine the display name, use the extended display name if the
2995 // enclosing class of the inherited member is in a different source 3427 // enclosing class of the inherited member is in a different source
2996 String displayName; 3428 String displayName;
2997 Element enclosingElement = inheritedMember.enclosingElement; 3429 Element enclosingElement = inheritedMember.enclosingElement;
2998 if (enclosingElement.source == _enclosingClass.source) { 3430 if (enclosingElement.source == _enclosingClass.source) {
2999 displayName = enclosingElement.displayName; 3431 displayName = enclosingElement.displayName;
3000 } else { 3432 } else {
3001 displayName = enclosingElement.getExtendedDisplayName(null); 3433 displayName = enclosingElement.getExtendedDisplayName(null);
3002 } 3434 }
3003 // report problem 3435
3004 _errorReporter.reportErrorForElement( 3436 _errorReporter.reportErrorForElement(
3005 CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE, 3437 CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE,
3006 staticMember, 3438 staticMember,
3007 [name, displayName]); 3439 [name, displayName]);
3008 return true;
3009 } 3440 }
3010 3441
3011 /** 3442 /**
3012 * Verify that if the given list [literal] has type arguments then there is 3443 * Verify that if the given list [literal] has type arguments then there is
3013 * exactly one. The [typeArguments] are the type arguments. 3444 * exactly one. The [typeArguments] are the type arguments.
3014 * 3445 *
3015 * See [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS]. 3446 * See [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS].
3016 */ 3447 */
3017 bool _checkForExpectedOneListTypeArgument( 3448 void _checkForExpectedOneListTypeArgument(
3018 ListLiteral literal, TypeArgumentList typeArguments) { 3449 ListLiteral literal, TypeArgumentList typeArguments) {
3019 // check number of type arguments 3450 // check number of type arguments
3020 int num = typeArguments.arguments.length; 3451 int num = typeArguments.arguments.length;
3021 if (num == 1) { 3452 if (num != 1) {
3022 return false; 3453 _errorReporter.reportErrorForNode(
3454 StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS,
3455 typeArguments,
3456 [num]);
3023 } 3457 }
3024 // report problem
3025 _errorReporter.reportErrorForNode(
3026 StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS,
3027 typeArguments,
3028 [num]);
3029 return true;
3030 } 3458 }
3031 3459
3032 /** 3460 /**
3033 * Verify that the given export [directive] has a unique name among other 3461 * Verify that the given export [directive] has a unique name among other
3034 * exported libraries. The [exportElement] is the [ExportElement] retrieved 3462 * exported libraries. The [exportElement] is the [ExportElement] retrieved
3035 * from the node, if the element in the node was `null`, then this method is 3463 * from the node, if the element in the node was `null`, then this method is
3036 * not called. The [exportedLibrary] is the library element containing the 3464 * not called. The [exportedLibrary] is the library element containing the
3037 * exported element. 3465 * exported element.
3038 * 3466 *
3039 * See [CompileTimeErrorCode.EXPORT_DUPLICATED_LIBRARY_NAME]. 3467 * See [CompileTimeErrorCode.EXPORT_DUPLICATED_LIBRARY_NAME].
3040 */ 3468 */
3041 bool _checkForExportDuplicateLibraryName(ExportDirective directive, 3469 void _checkForExportDuplicateLibraryName(ExportDirective directive,
3042 ExportElement exportElement, LibraryElement exportedLibrary) { 3470 ExportElement exportElement, LibraryElement exportedLibrary) {
3043 if (exportedLibrary == null) { 3471 if (exportedLibrary == null) {
3044 return false; 3472 return;
3045 } 3473 }
3046 String name = exportedLibrary.name; 3474 String name = exportedLibrary.name;
3047 // check if there is other exported library with the same name 3475 // check if there is other exported library with the same name
3048 LibraryElement prevLibrary = _nameToExportElement[name]; 3476 LibraryElement prevLibrary = _nameToExportElement[name];
3049 if (prevLibrary != null) { 3477 if (prevLibrary != null) {
3050 if (prevLibrary != exportedLibrary) { 3478 if (prevLibrary != exportedLibrary) {
3051 if (!name.isEmpty) { 3479 if (!name.isEmpty) {
3052 _errorReporter.reportErrorForNode( 3480 _errorReporter.reportErrorForNode(
3053 StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAMED, directive, [ 3481 StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAMED, directive, [
3054 prevLibrary.definingCompilationUnit.displayName, 3482 prevLibrary.definingCompilationUnit.displayName,
3055 exportedLibrary.definingCompilationUnit.displayName, 3483 exportedLibrary.definingCompilationUnit.displayName,
3056 name 3484 name
3057 ]); 3485 ]);
3058 } 3486 }
3059 return true; 3487 return;
3060 } 3488 }
3061 } else { 3489 } else {
3062 _nameToExportElement[name] = exportedLibrary; 3490 _nameToExportElement[name] = exportedLibrary;
3063 } 3491 }
3064 // OK
3065 return false;
3066 } 3492 }
3067 3493
3068 /** 3494 /**
3069 * Check that if the visiting library is not system, then any given library 3495 * Check that if the visiting library is not system, then any given library
3070 * should not be SDK internal library. The [exportElement] is the 3496 * should not be SDK internal library. The [exportElement] is the
3071 * [ExportElement] retrieved from the node, if the element in the node was 3497 * [ExportElement] retrieved from the node, if the element in the node was
3072 * `null`, then this method is not called. 3498 * `null`, then this method is not called.
3073 * 3499 *
3074 * See [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY]. 3500 * See [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY].
3075 */ 3501 */
3076 bool _checkForExportInternalLibrary( 3502 void _checkForExportInternalLibrary(
3077 ExportDirective directive, ExportElement exportElement) { 3503 ExportDirective directive, ExportElement exportElement) {
3078 if (_isInSystemLibrary) { 3504 if (_isInSystemLibrary) {
3079 return false; 3505 return;
3080 } 3506 }
3081 // should be private 3507 // should be private
3082 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; 3508 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk;
3083 String uri = exportElement.uri; 3509 String uri = exportElement.uri;
3084 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); 3510 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri);
3085 if (sdkLibrary == null) { 3511 if (sdkLibrary == null) {
3086 return false; 3512 return;
3087 } 3513 }
3088 if (!sdkLibrary.isInternal) { 3514 if (!sdkLibrary.isInternal) {
3089 return false; 3515 return;
3090 } 3516 }
3091 // report problem 3517
3092 _errorReporter.reportErrorForNode( 3518 _errorReporter.reportErrorForNode(
3093 CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, 3519 CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY,
3094 directive, 3520 directive,
3095 [directive.uri]); 3521 [directive.uri]);
3096 return true;
3097 } 3522 }
3098 3523
3099 /** 3524 /**
3100 * Verify that the given extends [clause] does not extend a deferred class. 3525 * Verify that the given extends [clause] does not extend a deferred class.
3101 * 3526 *
3102 * See [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS]. 3527 * See [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS].
3103 */ 3528 */
3104 bool _checkForExtendsDeferredClass(ExtendsClause clause) { 3529 void _checkForExtendsDeferredClass(ExtendsClause clause) {
3105 if (clause == null) { 3530 if (clause == null) {
3106 return false; 3531 return;
3107 } 3532 }
3108 return _checkForExtendsOrImplementsDeferredClass( 3533 _checkForExtendsOrImplementsDeferredClass(
3109 clause.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); 3534 clause.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS);
3110 } 3535 }
3111 3536
3112 /** 3537 /**
3113 * Verify that the given type [alias] does not extend a deferred class. 3538 * Verify that the given type [alias] does not extend a deferred class.
3114 * 3539 *
3115 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. 3540 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS].
3116 */ 3541 */
3117 bool _checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias alias) { 3542 void _checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias alias) {
3118 if (alias == null) { 3543 if (alias == null) {
3119 return false; 3544 return;
3120 } 3545 }
3121 return _checkForExtendsOrImplementsDeferredClass( 3546 _checkForExtendsOrImplementsDeferredClass(
3122 alias.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); 3547 alias.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS);
3123 } 3548 }
3124 3549
3125 /** 3550 /**
3126 * Verify that the given extends [clause] does not extend classes such as 3551 * Verify that the given extends [clause] does not extend classes such as
3127 * 'num' or 'String'. 3552 * 'num' or 'String'.
3128 * 3553 *
3129 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. 3554 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS].
3130 */ 3555 */
3131 bool _checkForExtendsDisallowedClass(ExtendsClause clause) { 3556 bool _checkForExtendsDisallowedClass(ExtendsClause clause) {
(...skipping 29 matching lines...) Expand all
3161 * [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS], 3586 * [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS],
3162 * [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS], and 3587 * [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS], and
3163 * [CompileTimeErrorCode.MIXIN_DEFERRED_CLASS]. 3588 * [CompileTimeErrorCode.MIXIN_DEFERRED_CLASS].
3164 */ 3589 */
3165 bool _checkForExtendsOrImplementsDeferredClass( 3590 bool _checkForExtendsOrImplementsDeferredClass(
3166 TypeName typeName, ErrorCode errorCode) { 3591 TypeName typeName, ErrorCode errorCode) {
3167 if (typeName.isSynthetic) { 3592 if (typeName.isSynthetic) {
3168 return false; 3593 return false;
3169 } 3594 }
3170 if (typeName.isDeferred) { 3595 if (typeName.isDeferred) {
3171 _errorReporter.reportErrorForNode( 3596 _errorReporter
3172 errorCode, typeName, [typeName.name.name]); 3597 .reportErrorForNode(errorCode, typeName, [typeName.name.name]);
3173 return true; 3598 return true;
3174 } 3599 }
3175 return false; 3600 return false;
3176 } 3601 }
3177 3602
3178 /** 3603 /**
3179 * Verify that the given [typeName] does not extend, implement or mixin 3604 * Verify that the given [typeName] does not extend, implement or mixin
3180 * classes such as 'num' or 'String'. 3605 * classes such as 'num' or 'String'.
3181 * 3606 *
3182 * See [_checkForExtendsDisallowedClass], 3607 * See [_checkForExtendsDisallowedClass],
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3224 _errorReporter.reportErrorForNode( 3649 _errorReporter.reportErrorForNode(
3225 errorCode, typeName, [disallowedType.displayName]); 3650 errorCode, typeName, [disallowedType.displayName]);
3226 return true; 3651 return true;
3227 } 3652 }
3228 } 3653 }
3229 return false; 3654 return false;
3230 } 3655 }
3231 3656
3232 /** 3657 /**
3233 * Verify that the given constructor field [initializer] has compatible field 3658 * Verify that the given constructor field [initializer] has compatible field
3234 * and initializer expression types. The [staticElement] is the static element 3659 * and initializer expression types. The [fieldElement] is the static element
3235 * from the name in the [ConstructorFieldInitializer]. 3660 * from the name in the [ConstructorFieldInitializer].
3236 * 3661 *
3237 * See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and 3662 * See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and
3238 * [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE]. 3663 * [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE].
3239 */ 3664 */
3240 bool _checkForFieldInitializerNotAssignable( 3665 void _checkForFieldInitializerNotAssignable(
3241 ConstructorFieldInitializer initializer, Element staticElement) { 3666 ConstructorFieldInitializer initializer, FieldElement fieldElement) {
3242 // prepare field element
3243 if (staticElement is! FieldElement) {
3244 return false;
3245 }
3246 FieldElement fieldElement = staticElement as FieldElement;
3247 // prepare field type 3667 // prepare field type
3248 DartType fieldType = fieldElement.type; 3668 DartType fieldType = fieldElement.type;
3249 // prepare expression type 3669 // prepare expression type
3250 Expression expression = initializer.expression; 3670 Expression expression = initializer.expression;
3251 if (expression == null) { 3671 if (expression == null) {
3252 return false; 3672 return;
3253 } 3673 }
3254 // test the static type of the expression 3674 // test the static type of the expression
3255 DartType staticType = getStaticType(expression); 3675 DartType staticType = getStaticType(expression);
3256 if (staticType == null) { 3676 if (staticType == null) {
3257 return false; 3677 return;
3258 } 3678 }
3259 if (_typeSystem.isAssignableTo(staticType, fieldType)) { 3679 if (_expressionIsAssignableAtType(expression, staticType, fieldType)) {
3260 return false; 3680 return;
3261 } 3681 }
3262 // report problem 3682 // report problem
3263 if (_isEnclosingConstructorConst) { 3683 if (_isEnclosingConstructorConst) {
3264 // TODO(paulberry): this error should be based on the actual type of the 3684 // TODO(paulberry): this error should be based on the actual type of the
3265 // constant, not the static type. See dartbug.com/21119. 3685 // constant, not the static type. See dartbug.com/21119.
3266 _errorReporter.reportTypeErrorForNode( 3686 _errorReporter.reportTypeErrorForNode(
3267 CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE , 3687 CheckedModeCompileTimeErrorCode
3688 .CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
3268 expression, 3689 expression,
3269 [staticType, fieldType]); 3690 [staticType, fieldType]);
3270 } 3691 }
3271 _errorReporter.reportTypeErrorForNode( 3692 _errorReporter.reportTypeErrorForNode(
3272 StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, 3693 StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE,
3273 expression, 3694 expression,
3274 [staticType, fieldType]); 3695 [staticType, fieldType]);
3275 return true;
3276 // TODO(brianwilkerson) Define a hint corresponding to these errors and 3696 // TODO(brianwilkerson) Define a hint corresponding to these errors and
3277 // report it if appropriate. 3697 // report it if appropriate.
3278 // // test the propagated type of the expression 3698 // // test the propagated type of the expression
3279 // Type propagatedType = expression.getPropagatedType(); 3699 // Type propagatedType = expression.getPropagatedType();
3280 // if (propagatedType != null && propagatedType.isAssignableTo(fieldType) ) { 3700 // if (propagatedType != null && propagatedType.isAssignableTo(fieldType) ) {
3281 // return false; 3701 // return false;
3282 // } 3702 // }
3283 // // report problem 3703 // // report problem
3284 // if (isEnclosingConstructorConst) { 3704 // if (isEnclosingConstructorConst) {
3285 // errorReporter.reportTypeErrorForNode( 3705 // errorReporter.reportTypeErrorForNode(
(...skipping 10 matching lines...) Expand all
3296 // } 3716 // }
3297 // return true; 3717 // return true;
3298 } 3718 }
3299 3719
3300 /** 3720 /**
3301 * Verify that the given field formal [parameter] is in a constructor 3721 * Verify that the given field formal [parameter] is in a constructor
3302 * declaration. 3722 * declaration.
3303 * 3723 *
3304 * See [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]. 3724 * See [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR].
3305 */ 3725 */
3306 bool _checkForFieldInitializingFormalRedirectingConstructor( 3726 void _checkForFieldInitializingFormalRedirectingConstructor(
3307 FieldFormalParameter parameter) { 3727 FieldFormalParameter parameter) {
3308 ConstructorDeclaration constructor = 3728 // prepare the node that should be a ConstructorDeclaration
3309 parameter.getAncestor((node) => node is ConstructorDeclaration); 3729 AstNode formalParameterList = parameter.parent;
3310 if (constructor == null) { 3730 if (formalParameterList is! FormalParameterList) {
3731 formalParameterList = formalParameterList?.parent;
3732 }
3733 AstNode constructor = formalParameterList?.parent;
3734 // now check whether the node is actually a ConstructorDeclaration
3735 if (constructor is ConstructorDeclaration) {
3736 // constructor cannot be a factory
3737 if (constructor.factoryKeyword != null) {
3738 _errorReporter.reportErrorForNode(
3739 CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR,
3740 parameter);
3741 return;
3742 }
3743 // constructor cannot have a redirection
3744 for (ConstructorInitializer initializer in constructor.initializers) {
3745 if (initializer is RedirectingConstructorInvocation) {
3746 _errorReporter.reportErrorForNode(
3747 CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
3748 parameter);
3749 return;
3750 }
3751 }
3752 } else {
3311 _errorReporter.reportErrorForNode( 3753 _errorReporter.reportErrorForNode(
3312 CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 3754 CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
3313 parameter); 3755 parameter);
3314 return true;
3315 } 3756 }
3316 // constructor cannot be a factory
3317 if (constructor.factoryKeyword != null) {
3318 _errorReporter.reportErrorForNode(
3319 CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR,
3320 parameter);
3321 return true;
3322 }
3323 // constructor cannot have a redirection
3324 for (ConstructorInitializer initializer in constructor.initializers) {
3325 if (initializer is RedirectingConstructorInvocation) {
3326 _errorReporter.reportErrorForNode(
3327 CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
3328 parameter);
3329 return true;
3330 }
3331 }
3332 // OK
3333 return false;
3334 } 3757 }
3335 3758
3336 /** 3759 /**
3337 * Verify that the given variable declaration [list] has only initialized 3760 * Verify that the given variable declaration [list] has only initialized
3338 * variables if the list is final or const. 3761 * variables if the list is final or const.
3339 * 3762 *
3340 * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and 3763 * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and
3341 * [StaticWarningCode.FINAL_NOT_INITIALIZED]. 3764 * [StaticWarningCode.FINAL_NOT_INITIALIZED].
3342 */ 3765 */
3343 bool _checkForFinalNotInitialized(VariableDeclarationList list) { 3766 void _checkForFinalNotInitialized(VariableDeclarationList list) {
3344 if (_isInNativeClass) { 3767 if (_isInNativeClass || list.isSynthetic) {
3345 return false; 3768 return;
3346 } 3769 }
3347 bool foundError = false; 3770
3348 if (!list.isSynthetic) { 3771 NodeList<VariableDeclaration> variables = list.variables;
3349 NodeList<VariableDeclaration> variables = list.variables; 3772 for (VariableDeclaration variable in variables) {
3350 for (VariableDeclaration variable in variables) { 3773 if (variable.initializer == null) {
3351 if (variable.initializer == null) { 3774 if (list.isConst) {
3352 if (list.isConst) { 3775 _errorReporter.reportErrorForNode(
3353 _errorReporter.reportErrorForNode( 3776 CompileTimeErrorCode.CONST_NOT_INITIALIZED,
3354 CompileTimeErrorCode.CONST_NOT_INITIALIZED, 3777 variable.name,
3355 variable.name, 3778 [variable.name.name]);
3356 [variable.name.name]); 3779 } else if (list.isFinal) {
3357 } else if (list.isFinal) { 3780 _errorReporter.reportErrorForNode(
3358 _errorReporter.reportErrorForNode( 3781 StaticWarningCode.FINAL_NOT_INITIALIZED,
3359 StaticWarningCode.FINAL_NOT_INITIALIZED, 3782 variable.name,
3360 variable.name, 3783 [variable.name.name]);
3361 [variable.name.name]);
3362 }
3363 foundError = true;
3364 } 3784 }
3365 } 3785 }
3366 } 3786 }
3367 return foundError;
3368 } 3787 }
3369 3788
3370 /** 3789 /**
3371 * Verify that final fields in the given clas [declaration] that are declared, 3790 * Verify that final fields in the given clas [declaration] that are declared,
3372 * without any constructors in the enclosing class, are initialized. Cases in 3791 * without any constructors in the enclosing class, are initialized. Cases in
3373 * which there is at least one constructor are handled at the end of 3792 * which there is at least one constructor are handled at the end of
3374 * [_checkForAllFinalInitializedErrorCodes]. 3793 * [_checkForAllFinalInitializedErrorCodes].
3375 * 3794 *
3376 * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and 3795 * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and
3377 * [StaticWarningCode.FINAL_NOT_INITIALIZED]. 3796 * [StaticWarningCode.FINAL_NOT_INITIALIZED].
3378 */ 3797 */
3379 bool _checkForFinalNotInitializedInClass(ClassDeclaration declaration) { 3798 void _checkForFinalNotInitializedInClass(ClassDeclaration declaration) {
3380 NodeList<ClassMember> classMembers = declaration.members; 3799 NodeList<ClassMember> classMembers = declaration.members;
3381 for (ClassMember classMember in classMembers) { 3800 for (ClassMember classMember in classMembers) {
3382 if (classMember is ConstructorDeclaration) { 3801 if (classMember is ConstructorDeclaration) {
3383 return false; 3802 return;
3384 } 3803 }
3385 } 3804 }
3386 bool foundError = false;
3387 for (ClassMember classMember in classMembers) { 3805 for (ClassMember classMember in classMembers) {
3388 if (classMember is FieldDeclaration && 3806 if (classMember is FieldDeclaration) {
3389 _checkForFinalNotInitialized(classMember.fields)) { 3807 _checkForFinalNotInitialized(classMember.fields);
3390 foundError = true;
3391 } 3808 }
3392 } 3809 }
3393 return foundError;
3394 } 3810 }
3395 3811
3396 /** 3812 /**
3397 * If the current function is async, async*, or sync*, verify that its 3813 * If the current function is async, async*, or sync*, verify that its
3398 * declared return type is assignable to Future, Stream, or Iterable, 3814 * declared return type is assignable to Future, Stream, or Iterable,
3399 * respectively. If not, report the error using [returnType]. 3815 * respectively. If not, report the error using [returnType].
3400 */ 3816 */
3401 void _checkForIllegalReturnType(TypeName returnType) { 3817 void _checkForIllegalReturnType(TypeName returnType) {
3402 if (returnType == null) { 3818 if (returnType == null) {
3403 // No declared return type, so the return type must be dynamic, which is 3819 // No declared return type, so the return type must be dynamic, which is
3404 // assignable to everything. 3820 // assignable to everything.
3405 return; 3821 return;
3406 } 3822 }
3407 if (_enclosingFunction.isAsynchronous) { 3823 if (_enclosingFunction.isAsynchronous) {
3408 if (_enclosingFunction.isGenerator) { 3824 if (_enclosingFunction.isGenerator) {
3409 if (!_typeSystem.isAssignableTo( 3825 _checkForIllegalReturnTypeCode(
3410 _enclosingFunction.returnType, _typeProvider.streamDynamicType)) { 3826 returnType,
3411 _errorReporter.reportErrorForNode( 3827 _typeProvider.streamDynamicType,
3412 StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE, 3828 StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE);
3413 returnType);
3414 }
3415 } else { 3829 } else {
3416 if (!_typeSystem.isAssignableTo( 3830 _checkForIllegalReturnTypeCode(
3417 _enclosingFunction.returnType, _typeProvider.futureDynamicType)) { 3831 returnType,
3418 _errorReporter.reportErrorForNode( 3832 _typeProvider.futureDynamicType,
3419 StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, returnType); 3833 StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE);
3420 }
3421 } 3834 }
3422 } else if (_enclosingFunction.isGenerator) { 3835 } else if (_enclosingFunction.isGenerator) {
3423 if (!_typeSystem.isAssignableTo( 3836 _checkForIllegalReturnTypeCode(
3424 _enclosingFunction.returnType, _typeProvider.iterableDynamicType)) { 3837 returnType,
3425 _errorReporter.reportErrorForNode( 3838 _typeProvider.iterableDynamicType,
3426 StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, 3839 StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE);
3427 returnType);
3428 }
3429 } 3840 }
3430 } 3841 }
3431 3842
3843 /**
3844 * If the current function is async, async*, or sync*, verify that its
3845 * declared return type is assignable to Future, Stream, or Iterable,
3846 * respectively. This is called by [_checkForIllegalReturnType] to check if
3847 * the declared [returnTypeName] is assignable to the required [expectedType]
3848 * and if not report [errorCode].
3849 */
3850 void _checkForIllegalReturnTypeCode(TypeName returnTypeName,
3851 DartType expectedType, StaticTypeWarningCode errorCode) {
3852 DartType returnType = _enclosingFunction.returnType;
3853 if (_options.strongMode) {
3854 //
3855 // When checking an async/sync*/async* method, we know the exact type
3856 // that will be returned (e.g. Future, Iterable, or Stream).
3857 //
3858 // For example an `async` function body will return a `Future<T>` for
3859 // some `T` (possibly `dynamic`).
3860 //
3861 // We allow the declared return type to be a supertype of that
3862 // (e.g. `dynamic`, `Object`), or Future<S> for some S.
3863 // (We assume the T <: S relation is checked elsewhere.)
3864 //
3865 // We do not allow user-defined subtypes of Future, because an `async`
3866 // method will never return those.
3867 //
3868 // To check for this, we ensure that `Future<bottom> <: returnType`.
3869 //
3870 // Similar logic applies for sync* and async*.
3871 //
3872 InterfaceType genericType = (expectedType.element as ClassElement).type;
3873 DartType lowerBound = genericType.instantiate([BottomTypeImpl.instance]);
3874 if (!_typeSystem.isSubtypeOf(lowerBound, returnType)) {
3875 _errorReporter.reportErrorForNode(errorCode, returnTypeName);
3876 }
3877 } else if (!_typeSystem.isAssignableTo(returnType, expectedType)) {
3878 _errorReporter.reportErrorForNode(errorCode, returnTypeName);
3879 }
3880 }
3881
3432 /** 3882 /**
3433 * Verify that the given implements [clause] does not implement classes that 3883 * Verify that the given implements [clause] does not implement classes that
3434 * are deferred. 3884 * are deferred.
3435 * 3885 *
3436 * See [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS]. 3886 * See [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS].
3437 */ 3887 */
3438 bool _checkForImplementsDeferredClass(ImplementsClause clause) { 3888 void _checkForImplementsDeferredClass(ImplementsClause clause) {
3439 if (clause == null) { 3889 if (clause == null) {
3440 return false; 3890 return;
3441 } 3891 }
3442 bool foundError = false;
3443 for (TypeName type in clause.interfaces) { 3892 for (TypeName type in clause.interfaces) {
3444 if (_checkForExtendsOrImplementsDeferredClass( 3893 _checkForExtendsOrImplementsDeferredClass(
3445 type, CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS)) { 3894 type, CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS);
3446 foundError = true;
3447 }
3448 } 3895 }
3449 return foundError;
3450 } 3896 }
3451 3897
3452 /** 3898 /**
3453 * Verify that the given implements [clause] does not implement classes such 3899 * Verify that the given implements [clause] does not implement classes such
3454 * as 'num' or 'String'. 3900 * as 'num' or 'String'.
3455 * 3901 *
3456 * See [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]. 3902 * See [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS].
3457 */ 3903 */
3458 bool _checkForImplementsDisallowedClass(ImplementsClause clause) { 3904 bool _checkForImplementsDisallowedClass(ImplementsClause clause) {
3459 if (clause == null) { 3905 if (clause == null) {
3460 return false; 3906 return false;
3461 } 3907 }
3462 bool foundError = false; 3908 bool foundError = false;
3463 for (TypeName type in clause.interfaces) { 3909 for (TypeName type in clause.interfaces) {
3464 if (_checkForExtendsOrImplementsDisallowedClass( 3910 if (_checkForExtendsOrImplementsDisallowedClass(
3465 type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) { 3911 type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) {
3466 foundError = true; 3912 foundError = true;
3467 } 3913 }
3468 } 3914 }
3469 return foundError; 3915 return foundError;
3470 } 3916 }
3471 3917
3918 void _checkForImplicitDynamicIdentifier(AstNode node, Identifier id) {
3919 if (_options.implicitDynamic) {
3920 return;
3921 }
3922 VariableElement variable = getVariableElement(id);
3923 if (variable != null &&
3924 variable.hasImplicitType &&
3925 variable.type.isDynamic) {
3926 ErrorCode errorCode;
3927 if (variable is FieldElement) {
3928 errorCode = StrongModeCode.IMPLICIT_DYNAMIC_FIELD;
3929 } else if (variable is ParameterElement) {
3930 errorCode = StrongModeCode.IMPLICIT_DYNAMIC_PARAMETER;
3931 } else {
3932 errorCode = StrongModeCode.IMPLICIT_DYNAMIC_VARIABLE;
3933 }
3934 _errorReporter.reportErrorForNode(errorCode, node, [id]);
3935 }
3936 }
3937
3938 void _checkForImplicitDynamicInvoke(InvocationExpression node) {
3939 if (_options.implicitDynamic ||
3940 node == null ||
3941 node.typeArguments != null) {
3942 return;
3943 }
3944 DartType invokeType = node.staticInvokeType;
3945 DartType declaredType = node.function.staticType;
3946 if (invokeType is FunctionType && declaredType is FunctionType) {
3947 Iterable<DartType> typeArgs =
3948 FunctionTypeImpl.recoverTypeArguments(declaredType, invokeType);
3949 if (typeArgs.any((t) => t.isDynamic)) {
3950 // Issue an error depending on what we're trying to call.
3951 Expression function = node.function;
3952 if (function is Identifier) {
3953 Element element = function.staticElement;
3954 if (element is MethodElement) {
3955 _errorReporter.reportErrorForNode(
3956 StrongModeCode.IMPLICIT_DYNAMIC_METHOD,
3957 node.function,
3958 [element.displayName, element.typeParameters.join(', ')]);
3959 return;
3960 }
3961
3962 if (element is FunctionElement) {
3963 _errorReporter.reportErrorForNode(
3964 StrongModeCode.IMPLICIT_DYNAMIC_FUNCTION,
3965 node.function,
3966 [element.displayName, element.typeParameters.join(', ')]);
3967 return;
3968 }
3969 }
3970
3971 // The catch all case if neither of those matched.
3972 // For example, invoking a function expression.
3973 _errorReporter.reportErrorForNode(
3974 StrongModeCode.IMPLICIT_DYNAMIC_INVOKE,
3975 node.function,
3976 [declaredType]);
3977 }
3978 }
3979 }
3980
3981 void _checkForImplicitDynamicReturn(AstNode node, ExecutableElement element) {
3982 if (_options.implicitDynamic) {
3983 return;
3984 }
3985 if (element is PropertyAccessorElement && element.isSetter) {
3986 return;
3987 }
3988 if (element != null &&
3989 element.hasImplicitReturnType &&
3990 element.returnType.isDynamic) {
3991 _errorReporter.reportErrorForNode(
3992 StrongModeCode.IMPLICIT_DYNAMIC_RETURN, node, [element.displayName]);
3993 }
3994 }
3995
3996 void _checkForImplicitDynamicType(TypeName node) {
3997 if (_options.implicitDynamic ||
3998 node == null ||
3999 node.typeArguments != null) {
4000 return;
4001 }
4002 DartType type = node.type;
4003 if (type is ParameterizedType &&
4004 type.typeArguments.isNotEmpty &&
4005 type.typeArguments.any((t) => t.isDynamic)) {
4006 _errorReporter.reportErrorForNode(
4007 StrongModeCode.IMPLICIT_DYNAMIC_TYPE, node, [type]);
4008 }
4009 }
4010
4011 void _checkForImplicitDynamicTypedLiteral(TypedLiteral node) {
4012 if (_options.implicitDynamic || node.typeArguments != null) {
4013 return;
4014 }
4015 DartType type = node.staticType;
4016 // It's an error if either the key or value was inferred as dynamic.
4017 if (type is InterfaceType && type.typeArguments.any((t) => t.isDynamic)) {
4018 ErrorCode errorCode = node is ListLiteral
4019 ? StrongModeCode.IMPLICIT_DYNAMIC_LIST_LITERAL
4020 : StrongModeCode.IMPLICIT_DYNAMIC_MAP_LITERAL;
4021 _errorReporter.reportErrorForNode(errorCode, node);
4022 }
4023 }
4024
3472 /** 4025 /**
3473 * Verify that if the given [identifier] is part of a constructor initializer, 4026 * Verify that if the given [identifier] is part of a constructor initializer,
3474 * then it does not implicitly reference 'this' expression. 4027 * then it does not implicitly reference 'this' expression.
3475 * 4028 *
3476 * See [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER], and 4029 * See [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER], and
3477 * [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]. 4030 * [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC].
3478 * TODO(scheglov) rename thid method 4031 * TODO(scheglov) rename thid method
3479 */ 4032 */
3480 bool _checkForImplicitThisReferenceInInitializer( 4033 void _checkForImplicitThisReferenceInInitializer(
3481 SimpleIdentifier identifier) { 4034 SimpleIdentifier identifier) {
3482 if (!_isInConstructorInitializer && 4035 if (!_isInConstructorInitializer &&
3483 !_isInStaticMethod && 4036 !_isInStaticMethod &&
3484 !_isInFactory && 4037 !_isInFactory &&
3485 !_isInInstanceVariableInitializer && 4038 !_isInInstanceVariableInitializer &&
3486 !_isInStaticVariableDeclaration) { 4039 !_isInStaticVariableDeclaration) {
3487 return false; 4040 return;
3488 } 4041 }
3489 // prepare element 4042 // prepare element
3490 Element element = identifier.staticElement; 4043 Element element = identifier.staticElement;
3491 if (!(element is MethodElement || element is PropertyAccessorElement)) { 4044 if (!(element is MethodElement || element is PropertyAccessorElement)) {
3492 return false; 4045 return;
3493 } 4046 }
3494 // static element 4047 // static element
3495 ExecutableElement executableElement = element as ExecutableElement; 4048 ExecutableElement executableElement = element as ExecutableElement;
3496 if (executableElement.isStatic) { 4049 if (executableElement.isStatic) {
3497 return false; 4050 return;
3498 } 4051 }
3499 // not a class member 4052 // not a class member
3500 Element enclosingElement = element.enclosingElement; 4053 Element enclosingElement = element.enclosingElement;
3501 if (enclosingElement is! ClassElement) { 4054 if (enclosingElement is! ClassElement) {
3502 return false; 4055 return;
3503 } 4056 }
3504 // comment 4057 // comment
3505 AstNode parent = identifier.parent; 4058 AstNode parent = identifier.parent;
3506 if (parent is CommentReference) { 4059 if (parent is CommentReference) {
3507 return false; 4060 return;
3508 } 4061 }
3509 // qualified method invocation 4062 // qualified method invocation
3510 if (parent is MethodInvocation) { 4063 if (parent is MethodInvocation) {
3511 MethodInvocation invocation = parent; 4064 if (identical(parent.methodName, identifier) &&
3512 if (identical(invocation.methodName, identifier) && 4065 parent.realTarget != null) {
3513 invocation.realTarget != null) { 4066 return;
3514 return false;
3515 } 4067 }
3516 } 4068 }
3517 // qualified property access 4069 // qualified property access
3518 if (parent is PropertyAccess) { 4070 if (parent is PropertyAccess) {
3519 PropertyAccess access = parent; 4071 if (identical(parent.propertyName, identifier) &&
3520 if (identical(access.propertyName, identifier) && 4072 parent.realTarget != null) {
3521 access.realTarget != null) { 4073 return;
3522 return false;
3523 } 4074 }
3524 } 4075 }
3525 if (parent is PrefixedIdentifier) { 4076 if (parent is PrefixedIdentifier) {
3526 PrefixedIdentifier prefixed = parent; 4077 if (identical(parent.identifier, identifier)) {
3527 if (identical(prefixed.identifier, identifier)) { 4078 return;
3528 return false;
3529 } 4079 }
3530 } 4080 }
3531 // report problem 4081
3532 if (_isInStaticMethod) { 4082 if (_isInStaticMethod) {
3533 _errorReporter.reportErrorForNode( 4083 _errorReporter.reportErrorForNode(
3534 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, identifier); 4084 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, identifier);
3535 } else if (_isInFactory) { 4085 } else if (_isInFactory) {
3536 _errorReporter.reportErrorForNode( 4086 _errorReporter.reportErrorForNode(
3537 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, identifier); 4087 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, identifier);
3538 } else { 4088 } else {
3539 _errorReporter.reportErrorForNode( 4089 _errorReporter.reportErrorForNode(
3540 CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, 4090 CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
3541 identifier); 4091 identifier);
3542 } 4092 }
3543 return true;
3544 } 4093 }
3545 4094
3546 /** 4095 /**
3547 * Verify that the given import [directive] has a unique name among other 4096 * Verify that the given import [directive] has a unique name among other
3548 * imported libraries. The [importElement] is the [ImportElement] retrieved 4097 * imported libraries. The [importElement] is the [ImportElement] retrieved
3549 * from the node, if the element in the node was `null`, then this method is 4098 * from the node, if the element in the node was `null`, then this method is
3550 * not called. 4099 * not called.
3551 * 4100 *
3552 * See [CompileTimeErrorCode.IMPORT_DUPLICATED_LIBRARY_NAME]. 4101 * See [CompileTimeErrorCode.IMPORT_DUPLICATED_LIBRARY_NAME].
3553 */ 4102 */
3554 bool _checkForImportDuplicateLibraryName( 4103 void _checkForImportDuplicateLibraryName(
3555 ImportDirective directive, ImportElement importElement) { 4104 ImportDirective directive, ImportElement importElement) {
3556 // prepare imported library 4105 // prepare imported library
3557 LibraryElement nodeLibrary = importElement.importedLibrary; 4106 LibraryElement nodeLibrary = importElement.importedLibrary;
3558 if (nodeLibrary == null) { 4107 if (nodeLibrary == null) {
3559 return false; 4108 return;
3560 } 4109 }
3561 String name = nodeLibrary.name; 4110 String name = nodeLibrary.name;
3562 // check if there is another imported library with the same name 4111 // check if there is another imported library with the same name
3563 LibraryElement prevLibrary = _nameToImportElement[name]; 4112 LibraryElement prevLibrary = _nameToImportElement[name];
3564 if (prevLibrary != null) { 4113 if (prevLibrary != null) {
3565 if (prevLibrary != nodeLibrary) { 4114 if (prevLibrary != nodeLibrary && !name.isEmpty) {
3566 if (!name.isEmpty) { 4115 _errorReporter.reportErrorForNode(
3567 _errorReporter.reportErrorForNode( 4116 StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAMED, directive, [
3568 StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAMED, directive, [ 4117 prevLibrary.definingCompilationUnit.displayName,
3569 prevLibrary.definingCompilationUnit.displayName, 4118 nodeLibrary.definingCompilationUnit.displayName,
3570 nodeLibrary.definingCompilationUnit.displayName, 4119 name
3571 name 4120 ]);
3572 ]);
3573 }
3574 return true;
3575 } 4121 }
3576 } else { 4122 } else {
3577 _nameToImportElement[name] = nodeLibrary; 4123 _nameToImportElement[name] = nodeLibrary;
3578 } 4124 }
3579 // OK
3580 return false;
3581 } 4125 }
3582 4126
3583 /** 4127 /**
3584 * Check that if the visiting library is not system, then any given library 4128 * Check that if the visiting library is not system, then any given library
3585 * should not be SDK internal library. The [importElement] is the 4129 * should not be SDK internal library. The [importElement] is the
3586 * [ImportElement] retrieved from the node, if the element in the node was 4130 * [ImportElement] retrieved from the node, if the element in the node was
3587 * `null`, then this method is not called 4131 * `null`, then this method is not called
3588 * 4132 *
3589 * See [CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY]. 4133 * See [CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY].
3590 */ 4134 */
3591 bool _checkForImportInternalLibrary( 4135 void _checkForImportInternalLibrary(
3592 ImportDirective directive, ImportElement importElement) { 4136 ImportDirective directive, ImportElement importElement) {
3593 if (_isInSystemLibrary) { 4137 if (_isInSystemLibrary) {
3594 return false; 4138 return;
3595 } 4139 }
3596 // should be private 4140 // should be private
3597 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; 4141 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk;
3598 String uri = importElement.uri; 4142 String uri = importElement.uri;
3599 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); 4143 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri);
3600 if (sdkLibrary == null) { 4144 if (sdkLibrary == null || !sdkLibrary.isInternal) {
3601 return false; 4145 return;
3602 } 4146 }
3603 if (!sdkLibrary.isInternal) { 4147
3604 return false;
3605 }
3606 // report problem
3607 _errorReporter.reportErrorForNode( 4148 _errorReporter.reportErrorForNode(
3608 CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, 4149 CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY,
3609 directive, 4150 directive,
3610 [directive.uri]); 4151 [directive.uri]);
3611 return true;
3612 } 4152 }
3613 4153
3614 /** 4154 /**
3615 * For each class declaration, this method is called which verifies that all 4155 * For each class declaration, this method is called which verifies that all
3616 * inherited members are inherited consistently. 4156 * inherited members are inherited consistently.
3617 * 4157 *
3618 * See [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]. 4158 * See [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE].
3619 */ 4159 */
3620 bool _checkForInconsistentMethodInheritance() { 4160 void _checkForInconsistentMethodInheritance() {
3621 // Ensure that the inheritance manager has a chance to generate all errors 4161 // Ensure that the inheritance manager has a chance to generate all errors
3622 // we may care about, note that we ensure that the interfaces data since 4162 // we may care about, note that we ensure that the interfaces data since
3623 // there are no errors. 4163 // there are no errors.
3624 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass); 4164 _inheritanceManager.getMembersInheritedFromInterfaces(_enclosingClass);
3625 HashSet<AnalysisError> errors = 4165 Set<AnalysisError> errors = _inheritanceManager.getErrors(_enclosingClass);
3626 _inheritanceManager.getErrors(_enclosingClass);
3627 if (errors == null || errors.isEmpty) { 4166 if (errors == null || errors.isEmpty) {
3628 return false; 4167 return;
3629 } 4168 }
3630 for (AnalysisError error in errors) { 4169 for (AnalysisError error in errors) {
3631 _errorReporter.reportError(error); 4170 _errorReporter.reportError(error);
3632 } 4171 }
3633 return true; 4172 return;
3634 } 4173 }
3635 4174
3636 /** 4175 /**
4176 * Check for a type mis-match between the iterable expression and the
4177 * assigned variable in a for-in statement.
4178 */
4179 void _checkForInIterable(ForEachStatement node) {
4180 // Ignore malformed for statements.
4181 if (node.identifier == null && node.loopVariable == null) {
4182 return;
4183 }
4184
4185 DartType iterableType = getStaticType(node.iterable);
4186 if (iterableType.isDynamic) {
4187 return;
4188 }
4189
4190 // The type of the loop variable.
4191 SimpleIdentifier variable = node.identifier ?? node.loopVariable.identifier;
4192 DartType variableType = getStaticType(variable);
4193
4194 DartType loopType = node.awaitKeyword != null
4195 ? _typeProvider.streamType
4196 : _typeProvider.iterableType;
4197
4198 // Use an explicit string instead of [loopType] to remove the "<E>".
4199 String loopTypeName = node.awaitKeyword != null ? "Stream" : "Iterable";
4200
4201 // The object being iterated has to implement Iterable<T> for some T that
4202 // is assignable to the variable's type.
4203 // TODO(rnystrom): Move this into mostSpecificTypeArgument()?
4204 iterableType = iterableType.resolveToBound(_typeProvider.objectType);
4205 DartType bestIterableType =
4206 _typeSystem.mostSpecificTypeArgument(iterableType, loopType);
4207
4208 // Allow it to be a supertype of Iterable<T> (basically just Object) and do
4209 // an implicit downcast to Iterable<dynamic>.
4210 if (bestIterableType == null) {
4211 if (_typeSystem.isSubtypeOf(loopType, iterableType)) {
4212 bestIterableType = DynamicTypeImpl.instance;
4213 }
4214 }
4215
4216 if (bestIterableType == null) {
4217 _errorReporter.reportTypeErrorForNode(
4218 StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE,
4219 node.iterable,
4220 [iterableType, loopTypeName]);
4221 } else if (!_typeSystem.isAssignableTo(bestIterableType, variableType)) {
4222 _errorReporter.reportTypeErrorForNode(
4223 StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE,
4224 node.iterable,
4225 [iterableType, loopTypeName, variableType]);
4226 }
4227 }
4228
4229 /**
3637 * Check that the given [typeReference] is not a type reference and that then 4230 * Check that the given [typeReference] is not a type reference and that then
3638 * the [name] is reference to an instance member. 4231 * the [name] is reference to an instance member.
3639 * 4232 *
3640 * See [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]. 4233 * See [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER].
3641 */ 4234 */
3642 bool _checkForInstanceAccessToStaticMember( 4235 void _checkForInstanceAccessToStaticMember(
3643 ClassElement typeReference, SimpleIdentifier name) { 4236 ClassElement typeReference, SimpleIdentifier name) {
3644 // OK, in comment 4237 // OK, in comment
3645 if (_isInComment) { 4238 if (_isInComment) {
3646 return false; 4239 return;
3647 } 4240 }
3648 // OK, target is a type 4241 // OK, target is a type
3649 if (typeReference != null) { 4242 if (typeReference != null) {
3650 return false; 4243 return;
3651 } 4244 }
3652 // prepare member Element 4245 // prepare member Element
3653 Element element = name.staticElement; 4246 Element element = name.staticElement;
3654 if (element is! ExecutableElement) { 4247 if (element is ExecutableElement) {
3655 return false; 4248 // OK, top-level element
4249 if (element.enclosingElement is! ClassElement) {
4250 return;
4251 }
4252 // OK, instance member
4253 if (!element.isStatic) {
4254 return;
4255 }
4256 _errorReporter.reportErrorForNode(
4257 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
4258 name,
4259 [name.name]);
3656 } 4260 }
3657 ExecutableElement executableElement = element as ExecutableElement;
3658 // OK, top-level element
3659 if (executableElement.enclosingElement is! ClassElement) {
3660 return false;
3661 }
3662 // OK, instance member
3663 if (!executableElement.isStatic) {
3664 return false;
3665 }
3666 // report problem
3667 _errorReporter.reportErrorForNode(
3668 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
3669 name,
3670 [name.name]);
3671 return true;
3672 } 4261 }
3673 4262
3674 /** 4263 /**
3675 * Check whether the given [executableElement] collides with the name of a 4264 * Check whether the given [executableElement] collides with the name of a
3676 * static method in one of its superclasses, and reports the appropriate 4265 * static method in one of its superclasses, and reports the appropriate
3677 * warning if it does. The [errorNameTarget] is the node to report problems 4266 * warning if it does. The [errorNameTarget] is the node to report problems
3678 * on. 4267 * on.
3679 * 4268 *
3680 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST ATIC]. 4269 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST ATIC].
3681 */ 4270 */
3682 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic( 4271 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic(
3683 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) { 4272 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) {
3684 String executableElementName = executableElement.name; 4273 String executableElementName = executableElement.name;
3685 if (executableElement is! PropertyAccessorElement && 4274 if (executableElement is! PropertyAccessorElement &&
3686 !executableElement.isOperator) { 4275 !executableElement.isOperator) {
3687 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>(); 4276 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
3688 InterfaceType superclassType = _enclosingClass.supertype; 4277 InterfaceType superclassType = _enclosingClass.supertype;
3689 ClassElement superclassElement = 4278 ClassElement superclassElement = superclassType?.element;
3690 superclassType == null ? null : superclassType.element;
3691 bool executableElementPrivate = 4279 bool executableElementPrivate =
3692 Identifier.isPrivateName(executableElementName); 4280 Identifier.isPrivateName(executableElementName);
3693 while (superclassElement != null && 4281 while (superclassElement != null &&
3694 !visitedClasses.contains(superclassElement)) { 4282 !visitedClasses.contains(superclassElement)) {
3695 visitedClasses.add(superclassElement); 4283 visitedClasses.add(superclassElement);
3696 LibraryElement superclassLibrary = superclassElement.library; 4284 LibraryElement superclassLibrary = superclassElement.library;
3697 // Check fields. 4285 // Check fields.
3698 FieldElement fieldElt = 4286 FieldElement fieldElt =
3699 superclassElement.getField(executableElementName); 4287 superclassElement.getField(executableElementName);
3700 if (fieldElt != null) { 4288 if (fieldElt != null) {
3701 // Ignore if private in a different library - cannot collide. 4289 // Ignore if private in a different library - cannot collide.
3702 if (executableElementPrivate && 4290 if (executableElementPrivate &&
3703 _currentLibrary != superclassLibrary) { 4291 _currentLibrary != superclassLibrary) {
3704 continue; 4292 continue;
3705 } 4293 }
3706 // instance vs. static 4294 // instance vs. static
3707 if (fieldElt.isStatic) { 4295 if (fieldElt.isStatic) {
3708 _errorReporter.reportErrorForNode( 4296 _errorReporter.reportErrorForNode(
3709 StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ STATIC, 4297 StaticWarningCode
4298 .INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
3710 errorNameTarget, 4299 errorNameTarget,
3711 [executableElementName, fieldElt.enclosingElement.displayName]); 4300 [executableElementName, fieldElt.enclosingElement.displayName]);
3712 return true; 4301 return true;
3713 } 4302 }
3714 } 4303 }
3715 // Check methods. 4304 // Check methods.
3716 List<MethodElement> methodElements = superclassElement.methods; 4305 List<MethodElement> methodElements = superclassElement.methods;
3717 for (MethodElement methodElement in methodElements) { 4306 int length = methodElements.length;
4307 for (int i = 0; i < length; i++) {
4308 MethodElement methodElement = methodElements[i];
3718 // We need the same name. 4309 // We need the same name.
3719 if (methodElement.name != executableElementName) { 4310 if (methodElement.name != executableElementName) {
3720 continue; 4311 continue;
3721 } 4312 }
3722 // Ignore if private in a different library - cannot collide. 4313 // Ignore if private in a different library - cannot collide.
3723 if (executableElementPrivate && 4314 if (executableElementPrivate &&
3724 _currentLibrary != superclassLibrary) { 4315 _currentLibrary != superclassLibrary) {
3725 continue; 4316 continue;
3726 } 4317 }
3727 // instance vs. static 4318 // instance vs. static
3728 if (methodElement.isStatic) { 4319 if (methodElement.isStatic) {
3729 _errorReporter.reportErrorForNode( 4320 _errorReporter.reportErrorForNode(
3730 StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ STATIC, 4321 StaticWarningCode
3731 errorNameTarget, [ 4322 .INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
3732 executableElementName, 4323 errorNameTarget,
3733 methodElement.enclosingElement.displayName 4324 [
3734 ]); 4325 executableElementName,
4326 methodElement.enclosingElement.displayName
4327 ]);
3735 return true; 4328 return true;
3736 } 4329 }
3737 } 4330 }
3738 superclassType = superclassElement.supertype; 4331 superclassType = superclassElement.supertype;
3739 superclassElement = 4332 superclassElement = superclassType?.element;
3740 superclassType == null ? null : superclassType.element;
3741 } 4333 }
3742 } 4334 }
3743 return false; 4335 return false;
3744 } 4336 }
3745 4337
3746 /** 4338 /**
3747 * Verify that an 'int' can be assigned to the parameter corresponding to the 4339 * Verify that an 'int' can be assigned to the parameter corresponding to the
3748 * given [argument]. This is used for prefix and postfix expressions where 4340 * given [argument]. This is used for prefix and postfix expressions where
3749 * the argument value is implicit. 4341 * the argument value is implicit.
3750 * 4342 *
3751 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. 4343 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
3752 */ 4344 */
3753 bool _checkForIntNotAssignable(Expression argument) { 4345 void _checkForIntNotAssignable(Expression argument) {
3754 if (argument == null) { 4346 if (argument == null) {
3755 return false; 4347 return;
3756 } 4348 }
3757 ParameterElement staticParameterElement = argument.staticParameterElement; 4349 ParameterElement staticParameterElement = argument.staticParameterElement;
3758 DartType staticParameterType = 4350 DartType staticParameterType = staticParameterElement?.type;
3759 staticParameterElement == null ? null : staticParameterElement.type; 4351 _checkForArgumentTypeNotAssignable(argument, staticParameterType, _intType,
3760 return _checkForArgumentTypeNotAssignable(argument, staticParameterType, 4352 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
3761 _intType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
3762 } 4353 }
3763 4354
3764 /** 4355 /**
3765 * Verify that the given [annotation] isn't defined in a deferred library. 4356 * Verify that the given [annotation] isn't defined in a deferred library.
3766 * 4357 *
3767 * See [CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY]. 4358 * See [CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY].
3768 */ 4359 */
3769 bool _checkForInvalidAnnotationFromDeferredLibrary(Annotation annotation) { 4360 void _checkForInvalidAnnotationFromDeferredLibrary(Annotation annotation) {
3770 Identifier nameIdentifier = annotation.name; 4361 Identifier nameIdentifier = annotation.name;
3771 if (nameIdentifier is PrefixedIdentifier) { 4362 if (nameIdentifier is PrefixedIdentifier && nameIdentifier.isDeferred) {
3772 if (nameIdentifier.isDeferred) { 4363 _errorReporter.reportErrorForNode(
3773 _errorReporter.reportErrorForNode( 4364 CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY,
3774 CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY, 4365 annotation.name);
3775 annotation.name);
3776 return true;
3777 }
3778 } 4366 }
3779 return false;
3780 } 4367 }
3781 4368
3782 /** 4369 /**
3783 * Verify that the given left hand side ([lhs]) and right hand side ([rhs]) 4370 * Verify that the given left hand side ([lhs]) and right hand side ([rhs])
3784 * represent a valid assignment. 4371 * represent a valid assignment.
3785 * 4372 *
3786 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT]. 4373 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT].
3787 */ 4374 */
3788 bool _checkForInvalidAssignment(Expression lhs, Expression rhs) { 4375 void _checkForInvalidAssignment(Expression lhs, Expression rhs) {
3789 if (lhs == null || rhs == null) { 4376 if (lhs == null || rhs == null) {
3790 return false; 4377 return;
3791 } 4378 }
3792 VariableElement leftVariableElement = getVariableElement(lhs); 4379 VariableElement leftVariableElement = getVariableElement(lhs);
3793 DartType leftType = (leftVariableElement == null) 4380 DartType leftType = (leftVariableElement == null)
3794 ? getStaticType(lhs) 4381 ? getStaticType(lhs)
3795 : leftVariableElement.type; 4382 : leftVariableElement.type;
3796 DartType staticRightType = getStaticType(rhs); 4383 _checkForAssignableExpression(
3797 if (!_typeSystem.isAssignableTo(staticRightType, leftType)) { 4384 rhs, leftType, StaticTypeWarningCode.INVALID_ASSIGNMENT);
3798 _errorReporter.reportTypeErrorForNode(
3799 StaticTypeWarningCode.INVALID_ASSIGNMENT,
3800 rhs,
3801 [staticRightType, leftType]);
3802 return true;
3803 }
3804 return false;
3805 } 4385 }
3806 4386
3807 /** 4387 /**
3808 * Given an [assignment] using a compound assignment operator, this verifies 4388 * Given an [assignment] using a compound assignment operator, this verifies
3809 * that the given assignment is valid. The [lhs] is the left hand side 4389 * that the given assignment is valid. The [lhs] is the left hand side
3810 * expression. The [rhs] is the right hand side expression. 4390 * expression. The [rhs] is the right hand side expression.
3811 * 4391 *
3812 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT]. 4392 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT].
3813 */ 4393 */
3814 bool _checkForInvalidCompoundAssignment( 4394 void _checkForInvalidCompoundAssignment(
3815 AssignmentExpression assignment, Expression lhs, Expression rhs) { 4395 AssignmentExpression assignment, Expression lhs, Expression rhs) {
3816 if (lhs == null) { 4396 if (lhs == null) {
3817 return false; 4397 return;
3818 } 4398 }
3819 VariableElement leftVariableElement = getVariableElement(lhs); 4399 DartType leftType = getStaticType(lhs);
3820 DartType leftType = (leftVariableElement == null) 4400 DartType rightType = getStaticType(assignment);
3821 ? getStaticType(lhs)
3822 : leftVariableElement.type;
3823 MethodElement invokedMethod = assignment.staticElement;
3824 if (invokedMethod == null) {
3825 return false;
3826 }
3827 DartType rightType = invokedMethod.type.returnType;
3828 if (leftType == null || rightType == null) {
3829 return false;
3830 }
3831 if (!_typeSystem.isAssignableTo(rightType, leftType)) { 4401 if (!_typeSystem.isAssignableTo(rightType, leftType)) {
3832 _errorReporter.reportTypeErrorForNode( 4402 _errorReporter.reportTypeErrorForNode(
3833 StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightType, leftType]); 4403 StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightType, leftType]);
3834 return true;
3835 } 4404 }
3836 return false;
3837 } 4405 }
3838 4406
3839 /** 4407 /**
3840 * Check the given [initializer] to ensure that the field being initialized is 4408 * Check the given [initializer] to ensure that the field being initialized is
3841 * a valid field. The [fieldName] is the field name from the 4409 * a valid field. The [fieldName] is the field name from the
3842 * [ConstructorFieldInitializer]. The [staticElement] is the static element 4410 * [ConstructorFieldInitializer]. The [staticElement] is the static element
3843 * from the name in the [ConstructorFieldInitializer]. 4411 * from the name in the [ConstructorFieldInitializer].
3844 */ 4412 */
3845 void _checkForInvalidField(ConstructorFieldInitializer initializer, 4413 void _checkForInvalidField(ConstructorFieldInitializer initializer,
3846 SimpleIdentifier fieldName, Element staticElement) { 4414 SimpleIdentifier fieldName, Element staticElement) {
3847 if (staticElement is FieldElement) { 4415 if (staticElement is FieldElement) {
3848 FieldElement fieldElement = staticElement; 4416 if (staticElement.isSynthetic) {
3849 if (fieldElement.isSynthetic) {
3850 _errorReporter.reportErrorForNode( 4417 _errorReporter.reportErrorForNode(
3851 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, 4418 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
3852 initializer, 4419 initializer,
3853 [fieldName]); 4420 [fieldName]);
3854 } else if (fieldElement.isStatic) { 4421 } else if (staticElement.isStatic) {
3855 _errorReporter.reportErrorForNode( 4422 _errorReporter.reportErrorForNode(
3856 CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, 4423 CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
3857 initializer, 4424 initializer,
3858 [fieldName]); 4425 [fieldName]);
3859 } 4426 }
3860 } else { 4427 } else {
3861 _errorReporter.reportErrorForNode( 4428 _errorReporter.reportErrorForNode(
3862 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, 4429 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
3863 initializer, 4430 initializer,
3864 [fieldName]); 4431 [fieldName]);
3865 return; 4432 return;
3866 } 4433 }
3867 } 4434 }
3868 4435
3869 /** 4436 /**
3870 * Check to see whether the given function [body] has a modifier associated 4437 * Check to see whether the given function [body] has a modifier associated
3871 * with it, and report it as an error if it does. 4438 * with it, and report it as an error if it does.
3872 */ 4439 */
3873 bool _checkForInvalidModifierOnBody( 4440 void _checkForInvalidModifierOnBody(
3874 FunctionBody body, CompileTimeErrorCode errorCode) { 4441 FunctionBody body, CompileTimeErrorCode errorCode) {
3875 sc.Token keyword = body.keyword; 4442 Token keyword = body.keyword;
3876 if (keyword != null) { 4443 if (keyword != null) {
3877 _errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]); 4444 _errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]);
3878 return true;
3879 } 4445 }
3880 return false;
3881 } 4446 }
3882 4447
3883 /** 4448 /**
3884 * Verify that the usage of the given 'this' is valid. 4449 * Verify that the usage of the given 'this' is valid.
3885 * 4450 *
3886 * See [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]. 4451 * See [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS].
3887 */ 4452 */
3888 bool _checkForInvalidReferenceToThis(ThisExpression expression) { 4453 void _checkForInvalidReferenceToThis(ThisExpression expression) {
3889 if (!_isThisInValidContext(expression)) { 4454 if (!_isThisInValidContext(expression)) {
3890 _errorReporter.reportErrorForNode( 4455 _errorReporter.reportErrorForNode(
3891 CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, expression); 4456 CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, expression);
3892 return true;
3893 } 4457 }
3894 return false;
3895 } 4458 }
3896 4459
3897 /** 4460 /**
3898 * Checks to ensure that the given list of type [arguments] does not have a 4461 * Checks to ensure that the given list of type [arguments] does not have a
3899 * type parameter as a type argument. The [errorCode] is either 4462 * type parameter as a type argument. The [errorCode] is either
3900 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or 4463 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or
3901 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP]. 4464 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP].
3902 */ 4465 */
3903 bool _checkForInvalidTypeArgumentInConstTypedLiteral( 4466 void _checkForInvalidTypeArgumentInConstTypedLiteral(
3904 NodeList<TypeName> arguments, ErrorCode errorCode) { 4467 NodeList<TypeName> arguments, ErrorCode errorCode) {
3905 bool foundError = false;
3906 for (TypeName typeName in arguments) { 4468 for (TypeName typeName in arguments) {
3907 if (typeName.type is TypeParameterType) { 4469 if (typeName.type is TypeParameterType) {
3908 _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); 4470 _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]);
3909 foundError = true;
3910 } 4471 }
3911 } 4472 }
3912 return foundError;
3913 } 4473 }
3914 4474
3915 /** 4475 /**
3916 * Verify that the elements given list [literal] are subtypes of the specified 4476 * Verify that the elements given list [literal] are subtypes of the list's
3917 * element type. The [typeArguments] are the type arguments. 4477 * static type.
3918 * 4478 *
3919 * See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and 4479 * See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and
3920 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]. 4480 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE].
3921 */ 4481 */
3922 bool _checkForListElementTypeNotAssignable( 4482 void _checkForListElementTypeNotAssignable(ListLiteral literal) {
3923 ListLiteral literal, TypeArgumentList typeArguments) { 4483 // Determine the list's element type. We base this on the static type and
3924 NodeList<TypeName> typeNames = typeArguments.arguments; 4484 // not the literal's type arguments because in strong mode, the type
3925 if (typeNames.length < 1) { 4485 // arguments may be inferred.
3926 return false; 4486 DartType listType = literal.staticType;
3927 } 4487 assert(listType is InterfaceTypeImpl);
3928 DartType listElementType = typeNames[0].type; 4488
4489 List<DartType> typeArguments =
4490 (listType as InterfaceTypeImpl).typeArguments;
4491 assert(typeArguments.length == 1);
4492
4493 DartType listElementType = typeArguments[0];
4494
3929 // Check every list element. 4495 // Check every list element.
3930 bool hasProblems = false;
3931 for (Expression element in literal.elements) { 4496 for (Expression element in literal.elements) {
3932 if (literal.constKeyword != null) { 4497 if (literal.constKeyword != null) {
3933 // TODO(paulberry): this error should be based on the actual type of the 4498 // TODO(paulberry): this error should be based on the actual type of the
3934 // list element, not the static type. See dartbug.com/21119. 4499 // list element, not the static type. See dartbug.com/21119.
3935 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( 4500 _checkForArgumentTypeNotAssignableWithExpectedTypes(
3936 element, 4501 element,
3937 listElementType, 4502 listElementType,
3938 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { 4503 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE);
3939 hasProblems = true;
3940 }
3941 } 4504 }
3942 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( 4505 _checkForArgumentTypeNotAssignableWithExpectedTypes(element,
3943 element, 4506 listElementType, StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE);
3944 listElementType,
3945 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) {
3946 hasProblems = true;
3947 }
3948 } 4507 }
3949 return hasProblems;
3950 } 4508 }
3951 4509
3952 /** 4510 /**
3953 * Verify that the key/value of entries of the given map [literal] are 4511 * Verify that the key/value of entries of the given map [literal] are
3954 * subtypes of the key/value types specified in the type arguments. The 4512 * subtypes of the map's static type.
3955 * [typeArguments] are the type arguments.
3956 * 4513 *
3957 * See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], 4514 * See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE],
3958 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], 4515 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE],
3959 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and 4516 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and
3960 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. 4517 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE].
3961 */ 4518 */
3962 bool _checkForMapTypeNotAssignable( 4519 void _checkForMapTypeNotAssignable(MapLiteral literal) {
3963 MapLiteral literal, TypeArgumentList typeArguments) { 4520 // Determine the map's key and value types. We base this on the static type
3964 // Prepare maps key/value types. 4521 // and not the literal's type arguments because in strong mode, the type
3965 NodeList<TypeName> typeNames = typeArguments.arguments; 4522 // arguments may be inferred.
3966 if (typeNames.length < 2) { 4523 DartType mapType = literal.staticType;
3967 return false; 4524 assert(mapType is InterfaceTypeImpl);
3968 } 4525
3969 DartType keyType = typeNames[0].type; 4526 List<DartType> typeArguments = (mapType as InterfaceTypeImpl).typeArguments;
3970 DartType valueType = typeNames[1].type; 4527 assert(typeArguments.length == 2);
3971 // Check every map entry. 4528 DartType keyType = typeArguments[0];
3972 bool hasProblems = false; 4529 DartType valueType = typeArguments[1];
4530
3973 NodeList<MapLiteralEntry> entries = literal.entries; 4531 NodeList<MapLiteralEntry> entries = literal.entries;
3974 for (MapLiteralEntry entry in entries) { 4532 for (MapLiteralEntry entry in entries) {
3975 Expression key = entry.key; 4533 Expression key = entry.key;
3976 Expression value = entry.value; 4534 Expression value = entry.value;
3977 if (literal.constKeyword != null) { 4535 if (literal.constKeyword != null) {
3978 // TODO(paulberry): this error should be based on the actual type of the 4536 // TODO(paulberry): this error should be based on the actual type of the
3979 // list element, not the static type. See dartbug.com/21119. 4537 // list element, not the static type. See dartbug.com/21119.
3980 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(key, keyType, 4538 _checkForArgumentTypeNotAssignableWithExpectedTypes(key, keyType,
3981 CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) { 4539 CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE);
3982 hasProblems = true; 4540 _checkForArgumentTypeNotAssignableWithExpectedTypes(value, valueType,
3983 } 4541 CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE);
3984 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
3985 value,
3986 valueType,
3987 CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) {
3988 hasProblems = true;
3989 }
3990 } 4542 }
3991 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( 4543 _checkForArgumentTypeNotAssignableWithExpectedTypes(
3992 key, keyType, StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) { 4544 key, keyType, StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE);
3993 hasProblems = true; 4545 _checkForArgumentTypeNotAssignableWithExpectedTypes(
3994 } 4546 value, valueType, StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE);
3995 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
3996 value, valueType, StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) {
3997 hasProblems = true;
3998 }
3999 } 4547 }
4000 return hasProblems;
4001 } 4548 }
4002 4549
4003 /** 4550 /**
4004 * Verify that the [_enclosingClass] does not define members with the same nam e 4551 * Verify that the [_enclosingClass] does not define members with the same nam e
4005 * as the enclosing class. 4552 * as the enclosing class.
4006 * 4553 *
4007 * See [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]. 4554 * See [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME].
4008 */ 4555 */
4009 bool _checkForMemberWithClassName() { 4556 void _checkForMemberWithClassName() {
4010 if (_enclosingClass == null) { 4557 if (_enclosingClass == null) {
4011 return false; 4558 return;
4012 } 4559 }
4013 String className = _enclosingClass.name; 4560 String className = _enclosingClass.name;
4014 if (className == null) { 4561 if (className == null) {
4015 return false; 4562 return;
4016 } 4563 }
4017 bool problemReported = false; 4564
4018 // check accessors 4565 // check accessors
4019 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { 4566 for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
4020 if (className == accessor.name) { 4567 if (className == accessor.name) {
4021 _errorReporter.reportErrorForElement( 4568 _errorReporter.reportErrorForElement(
4022 CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME, accessor); 4569 CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME, accessor);
4023 problemReported = true;
4024 } 4570 }
4025 } 4571 }
4026 // don't check methods, they would be constructors 4572 // don't check methods, they would be constructors
4027 // done
4028 return problemReported;
4029 } 4573 }
4030 4574
4031 /** 4575 /**
4032 * Check to make sure that all similarly typed accessors are of the same type 4576 * Check to make sure that all similarly typed accessors are of the same type
4033 * (including inherited accessors). 4577 * (including inherited accessors).
4034 * 4578 *
4035 * See [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES], and 4579 * See [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES], and
4036 * [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE]. 4580 * [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE].
4037 */ 4581 */
4038 bool _checkForMismatchedAccessorTypes( 4582 void _checkForMismatchedAccessorTypes(
4039 Declaration accessorDeclaration, String accessorTextName) { 4583 Declaration accessorDeclaration, String accessorTextName) {
4040 ExecutableElement accessorElement = 4584 ExecutableElement accessorElement =
4041 accessorDeclaration.element as ExecutableElement; 4585 accessorDeclaration.element as ExecutableElement;
4042 if (accessorElement is! PropertyAccessorElement) { 4586 if (accessorElement is PropertyAccessorElement) {
4043 return false; 4587 PropertyAccessorElement counterpartAccessor = null;
4044 } 4588 ClassElement enclosingClassForCounterpart = null;
4045 PropertyAccessorElement propertyAccessorElement = 4589 if (accessorElement.isGetter) {
4046 accessorElement as PropertyAccessorElement; 4590 counterpartAccessor = accessorElement.correspondingSetter;
4047 PropertyAccessorElement counterpartAccessor = null; 4591 } else {
4048 ClassElement enclosingClassForCounterpart = null; 4592 counterpartAccessor = accessorElement.correspondingGetter;
4049 if (propertyAccessorElement.isGetter) { 4593 // If the setter and getter are in the same enclosing element, return,
4050 counterpartAccessor = propertyAccessorElement.correspondingSetter; 4594 // this prevents having MISMATCHED_GETTER_AND_SETTER_TYPES reported twic e.
4051 } else { 4595 if (counterpartAccessor != null &&
4052 counterpartAccessor = propertyAccessorElement.correspondingGetter; 4596 identical(counterpartAccessor.enclosingElement,
4053 // If the setter and getter are in the same enclosing element, return, 4597 accessorElement.enclosingElement)) {
4054 // this prevents having MISMATCHED_GETTER_AND_SETTER_TYPES reported twice. 4598 return;
4055 if (counterpartAccessor != null &&
4056 identical(counterpartAccessor.enclosingElement,
4057 propertyAccessorElement.enclosingElement)) {
4058 return false;
4059 }
4060 }
4061 if (counterpartAccessor == null) {
4062 // If the accessor is declared in a class, check the superclasses.
4063 if (_enclosingClass != null) {
4064 // Figure out the correct identifier to lookup in the inheritance graph,
4065 // if 'x', then 'x=', or if 'x=', then 'x'.
4066 String lookupIdentifier = propertyAccessorElement.name;
4067 if (StringUtilities.endsWithChar(lookupIdentifier, 0x3D)) {
4068 lookupIdentifier =
4069 lookupIdentifier.substring(0, lookupIdentifier.length - 1);
4070 } else {
4071 lookupIdentifier += "=";
4072 }
4073 // lookup with the identifier.
4074 ExecutableElement elementFromInheritance = _inheritanceManager
4075 .lookupInheritance(_enclosingClass, lookupIdentifier);
4076 // Verify that we found something, and that it is an accessor
4077 if (elementFromInheritance != null &&
4078 elementFromInheritance is PropertyAccessorElement) {
4079 enclosingClassForCounterpart =
4080 elementFromInheritance.enclosingElement as ClassElement;
4081 counterpartAccessor = elementFromInheritance;
4082 } 4599 }
4083 } 4600 }
4084 if (counterpartAccessor == null) { 4601 if (counterpartAccessor == null) {
4085 return false; 4602 // If the accessor is declared in a class, check the superclasses.
4603 if (_enclosingClass != null) {
4604 // Figure out the correct identifier to lookup in the inheritance grap h,
4605 // if 'x', then 'x=', or if 'x=', then 'x'.
4606 String lookupIdentifier = accessorElement.name;
4607 if (StringUtilities.endsWithChar(lookupIdentifier, 0x3D)) {
4608 lookupIdentifier =
4609 lookupIdentifier.substring(0, lookupIdentifier.length - 1);
4610 } else {
4611 lookupIdentifier += "=";
4612 }
4613 // lookup with the identifier.
4614 ExecutableElement elementFromInheritance = _inheritanceManager
4615 .lookupInheritance(_enclosingClass, lookupIdentifier);
4616 // Verify that we found something, and that it is an accessor
4617 if (elementFromInheritance != null &&
4618 elementFromInheritance is PropertyAccessorElement) {
4619 enclosingClassForCounterpart =
4620 elementFromInheritance.enclosingElement as ClassElement;
4621 counterpartAccessor = elementFromInheritance;
4622 }
4623 }
4624 if (counterpartAccessor == null) {
4625 return;
4626 }
4627 }
4628 // Default of null == no accessor or no type (dynamic)
4629 DartType getterType = null;
4630 DartType setterType = null;
4631 // Get an existing counterpart accessor if any.
4632 if (accessorElement.isGetter) {
4633 getterType = _getGetterType(accessorElement);
4634 setterType = _getSetterType(counterpartAccessor);
4635 } else if (accessorElement.isSetter) {
4636 setterType = _getSetterType(accessorElement);
4637 getterType = _getGetterType(counterpartAccessor);
4638 }
4639 // If either types are not assignable to each other, report an error
4640 // (if the getter is null, it is dynamic which is assignable to everything ).
4641 if (setterType != null &&
4642 getterType != null &&
4643 !_typeSystem.isAssignableTo(getterType, setterType)) {
4644 if (enclosingClassForCounterpart == null) {
4645 _errorReporter.reportTypeErrorForNode(
4646 StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
4647 accessorDeclaration,
4648 [accessorTextName, setterType, getterType]);
4649 } else {
4650 _errorReporter.reportTypeErrorForNode(
4651 StaticWarningCode
4652 .MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,
4653 accessorDeclaration,
4654 [
4655 accessorTextName,
4656 setterType,
4657 getterType,
4658 enclosingClassForCounterpart.displayName
4659 ]);
4660 }
4086 } 4661 }
4087 } 4662 }
4088 // Default of null == no accessor or no type (dynamic)
4089 DartType getterType = null;
4090 DartType setterType = null;
4091 // Get an existing counterpart accessor if any.
4092 if (propertyAccessorElement.isGetter) {
4093 getterType = _getGetterType(propertyAccessorElement);
4094 setterType = _getSetterType(counterpartAccessor);
4095 } else if (propertyAccessorElement.isSetter) {
4096 setterType = _getSetterType(propertyAccessorElement);
4097 getterType = _getGetterType(counterpartAccessor);
4098 }
4099 // If either types are not assignable to each other, report an error
4100 // (if the getter is null, it is dynamic which is assignable to everything).
4101 if (setterType != null &&
4102 getterType != null &&
4103 !_typeSystem.isAssignableTo(getterType, setterType)) {
4104 if (enclosingClassForCounterpart == null) {
4105 _errorReporter.reportTypeErrorForNode(
4106 StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
4107 accessorDeclaration,
4108 [accessorTextName, setterType, getterType]);
4109 return true;
4110 } else {
4111 _errorReporter.reportTypeErrorForNode(
4112 StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,
4113 accessorDeclaration, [
4114 accessorTextName,
4115 setterType,
4116 getterType,
4117 enclosingClassForCounterpart.displayName
4118 ]);
4119 }
4120 }
4121 return false;
4122 } 4663 }
4123 4664
4124 /** 4665 /**
4125 * Check to make sure that the given switch [statement] whose static type is 4666 * Check to make sure that the given switch [statement] whose static type is
4126 * an enum type either have a default case or include all of the enum 4667 * an enum type either have a default case or include all of the enum
4127 * constants. 4668 * constants.
4128 */ 4669 */
4129 bool _checkForMissingEnumConstantInSwitch(SwitchStatement statement) { 4670 void _checkForMissingEnumConstantInSwitch(SwitchStatement statement) {
4130 // TODO(brianwilkerson) This needs to be checked after constant values have 4671 // TODO(brianwilkerson) This needs to be checked after constant values have
4131 // been computed. 4672 // been computed.
4132 Expression expression = statement.expression; 4673 Expression expression = statement.expression;
4133 DartType expressionType = getStaticType(expression); 4674 DartType expressionType = getStaticType(expression);
4134 if (expressionType == null) { 4675 if (expressionType == null) {
4135 return false; 4676 return;
4136 } 4677 }
4137 Element expressionElement = expressionType.element; 4678 Element expressionElement = expressionType.element;
4138 if (expressionElement is! ClassElement) { 4679 if (expressionElement is ClassElement) {
4139 return false; 4680 if (!expressionElement.isEnum) {
4140 } 4681 return;
4141 ClassElement classElement = expressionElement as ClassElement; 4682 }
4142 if (!classElement.isEnum) { 4683 List<String> constantNames = <String>[];
4143 return false; 4684 List<FieldElement> fields = expressionElement.fields;
4144 } 4685 int fieldCount = fields.length;
4145 List<String> constantNames = new List<String>(); 4686 for (int i = 0; i < fieldCount; i++) {
4146 List<FieldElement> fields = classElement.fields; 4687 FieldElement field = fields[i];
4147 int fieldCount = fields.length; 4688 if (field.isStatic && !field.isSynthetic) {
4148 for (int i = 0; i < fieldCount; i++) { 4689 constantNames.add(field.name);
4149 FieldElement field = fields[i]; 4690 }
4150 if (field.isStatic && !field.isSynthetic) { 4691 }
4151 constantNames.add(field.name); 4692 NodeList<SwitchMember> members = statement.members;
4693 int memberCount = members.length;
4694 for (int i = 0; i < memberCount; i++) {
4695 SwitchMember member = members[i];
4696 if (member is SwitchDefault) {
4697 return;
4698 }
4699 String constantName =
4700 _getConstantName((member as SwitchCase).expression);
4701 if (constantName != null) {
4702 constantNames.remove(constantName);
4703 }
4704 }
4705 if (constantNames.isEmpty) {
4706 return;
4707 }
4708 for (int i = 0; i < constantNames.length; i++) {
4709 int offset = statement.offset;
4710 int end = statement.rightParenthesis.end;
4711 _errorReporter.reportErrorForOffset(
4712 StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
4713 offset,
4714 end - offset,
4715 [constantNames[i]]);
4152 } 4716 }
4153 } 4717 }
4154 NodeList<SwitchMember> members = statement.members; 4718 }
4155 int memberCount = members.length; 4719
4156 for (int i = 0; i < memberCount; i++) { 4720 void _checkForMissingJSLibAnnotation(Annotation node) {
4157 SwitchMember member = members[i]; 4721 if (node.elementAnnotation?.isJS ?? false) {
4158 if (member is SwitchDefault) { 4722 if (_currentLibrary.isJS != true) {
4159 return false; 4723 _errorReporter.reportErrorForNode(
4160 } 4724 HintCode.MISSING_JS_LIB_ANNOTATION, node);
4161 String constantName = _getConstantName((member as SwitchCase).expression);
4162 if (constantName != null) {
4163 constantNames.remove(constantName);
4164 } 4725 }
4165 } 4726 }
4166 int nameCount = constantNames.length;
4167 if (nameCount == 0) {
4168 return false;
4169 }
4170 for (int i = 0; i < nameCount; i++) {
4171 int offset = statement.offset;
4172 int end = statement.rightParenthesis.end;
4173 _errorReporter.reportErrorForOffset(
4174 CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
4175 offset,
4176 end - offset,
4177 [constantNames[i]]);
4178 }
4179 return true;
4180 } 4727 }
4181 4728
4182 /** 4729 /**
4183 * Verify that the given function [body] does not contain return statements 4730 * Verify that the given function [body] does not contain return statements
4184 * that both have and do not have return values. 4731 * that both have and do not have return values.
4185 * 4732 *
4186 * See [StaticWarningCode.MIXED_RETURN_TYPES]. 4733 * See [StaticWarningCode.MIXED_RETURN_TYPES].
4187 */ 4734 */
4188 bool _checkForMixedReturns(BlockFunctionBody body) { 4735 void _checkForMixedReturns(BlockFunctionBody body) {
4189 if (_hasReturnWithoutValue) { 4736 if (_hasReturnWithoutValue) {
4190 return false; 4737 return;
4191 } 4738 }
4192 int withCount = _returnsWith.length; 4739 if (_returnsWith.isNotEmpty && _returnsWithout.isNotEmpty) {
4193 int withoutCount = _returnsWithout.length; 4740 for (ReturnStatement returnWith in _returnsWith) {
4194 if (withCount > 0 && withoutCount > 0) { 4741 _errorReporter.reportErrorForToken(
4195 for (int i = 0; i < withCount; i++) { 4742 StaticWarningCode.MIXED_RETURN_TYPES, returnWith.returnKeyword);
4196 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES,
4197 _returnsWith[i].returnKeyword);
4198 } 4743 }
4199 for (int i = 0; i < withoutCount; i++) { 4744 for (ReturnStatement returnWithout in _returnsWithout) {
4200 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, 4745 _errorReporter.reportErrorForToken(
4201 _returnsWithout[i].returnKeyword); 4746 StaticWarningCode.MIXED_RETURN_TYPES, returnWithout.returnKeyword);
4202 } 4747 }
4203 return true;
4204 } 4748 }
4205 return false;
4206 } 4749 }
4207 4750
4208 /** 4751 /**
4209 * Verify that the given mixin does not have an explicitly declared 4752 * Verify that the given mixin does not have an explicitly declared
4210 * constructor. The [mixinName] is the node to report problem on. The 4753 * constructor. The [mixinName] is the node to report problem on. The
4211 * [mixinElement] is the mixing to evaluate. 4754 * [mixinElement] is the mixing to evaluate.
4212 * 4755 *
4213 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]. 4756 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR].
4214 */ 4757 */
4215 bool _checkForMixinDeclaresConstructor( 4758 bool _checkForMixinDeclaresConstructor(
4216 TypeName mixinName, ClassElement mixinElement) { 4759 TypeName mixinName, ClassElement mixinElement) {
4217 for (ConstructorElement constructor in mixinElement.constructors) { 4760 for (ConstructorElement constructor in mixinElement.constructors) {
4218 if (!constructor.isSynthetic && !constructor.isFactory) { 4761 if (!constructor.isSynthetic && !constructor.isFactory) {
4219 _errorReporter.reportErrorForNode( 4762 _errorReporter.reportErrorForNode(
4220 CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, 4763 CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR,
4221 mixinName, 4764 mixinName,
4222 [mixinElement.name]); 4765 [mixinElement.name]);
4223 return true; 4766 return true;
4224 } 4767 }
4225 } 4768 }
4226 return false; 4769 return false;
4227 } 4770 }
4228 4771
4229 /** 4772 /**
4230 * Report the error [CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS] if 4773 * Report the error [CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS] if
4231 * appropriate. 4774 * appropriate.
4232 */ 4775 */
4233 void _checkForMixinHasNoConstructors(AstNode node) { 4776 void _checkForMixinHasNoConstructors(AstNode node) {
4234 if ((_enclosingClass as ClassElementImpl).doesMixinLackConstructors) { 4777 if (_enclosingClass.doesMixinLackConstructors) {
4235 ErrorCode errorCode = CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS; 4778 ErrorCode errorCode = CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS;
4236 _errorReporter.reportErrorForNode( 4779 _errorReporter
4237 errorCode, node, [_enclosingClass.supertype]); 4780 .reportErrorForNode(errorCode, node, [_enclosingClass.supertype]);
4238 } 4781 }
4239 } 4782 }
4240 4783
4241 /** 4784 /**
4242 * Verify that the given mixin has the 'Object' superclass. The [mixinName] is 4785 * Verify that the given mixin has the 'Object' superclass. The [mixinName] is
4243 * the node to report problem on. The [mixinElement] is the mixing to 4786 * the node to report problem on. The [mixinElement] is the mixing to
4244 * evaluate. 4787 * evaluate.
4245 * 4788 *
4246 * See [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]. 4789 * See [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT].
4247 */ 4790 */
(...skipping 29 matching lines...) Expand all
4277 [mixinElement.name]); 4820 [mixinElement.name]);
4278 } 4821 }
4279 return false; 4822 return false;
4280 } 4823 }
4281 4824
4282 /** 4825 /**
4283 * Verify that the given [constructor] has at most one 'super' initializer. 4826 * Verify that the given [constructor] has at most one 'super' initializer.
4284 * 4827 *
4285 * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]. 4828 * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS].
4286 */ 4829 */
4287 bool _checkForMultipleSuperInitializers(ConstructorDeclaration constructor) { 4830 void _checkForMultipleSuperInitializers(ConstructorDeclaration constructor) {
4288 int numSuperInitializers = 0; 4831 bool hasSuperInitializer = false;
4289 for (ConstructorInitializer initializer in constructor.initializers) { 4832 for (ConstructorInitializer initializer in constructor.initializers) {
4290 if (initializer is SuperConstructorInvocation) { 4833 if (initializer is SuperConstructorInvocation) {
4291 numSuperInitializers++; 4834 if (hasSuperInitializer) {
4292 if (numSuperInitializers > 1) {
4293 _errorReporter.reportErrorForNode( 4835 _errorReporter.reportErrorForNode(
4294 CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer); 4836 CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer);
4295 } 4837 }
4838 hasSuperInitializer = true;
4296 } 4839 }
4297 } 4840 }
4298 return numSuperInitializers > 0; 4841 }
4842
4843 void _checkForMustCallSuper(MethodDeclaration node) {
4844 MethodElement element = _findOverriddenMemberThatMustCallSuper(node);
4845 if (element != null) {
4846 _InvocationCollector collector = new _InvocationCollector();
4847 node.accept(collector);
4848 if (!collector.superCalls.contains(element.name)) {
4849 _errorReporter.reportErrorForNode(HintCode.MUST_CALL_SUPER, node.name,
4850 [element.enclosingElement.name]);
4851 }
4852 }
4299 } 4853 }
4300 4854
4301 /** 4855 /**
4302 * Checks to ensure that the given native function [body] is in SDK code. 4856 * Checks to ensure that the given native function [body] is in SDK code.
4303 * 4857 *
4304 * See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]. 4858 * See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE].
4305 */ 4859 */
4306 bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody body) { 4860 void _checkForNativeFunctionBodyInNonSdkCode(NativeFunctionBody body) {
4307 if (!_isInSystemLibrary && !_hasExtUri) { 4861 if (!_isInSystemLibrary && !_hasExtUri) {
4308 _errorReporter.reportErrorForNode( 4862 _errorReporter.reportErrorForNode(
4309 ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, body); 4863 ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, body);
4310 return true;
4311 } 4864 }
4312 return false;
4313 } 4865 }
4314 4866
4315 /** 4867 /**
4316 * Verify that the given instance creation [expression] invokes an existing 4868 * Verify that the given instance creation [expression] invokes an existing
4317 * constructor. The [constructorName] is the constructor name. The [typeName] 4869 * constructor. The [constructorName] is the constructor name. The [typeName]
4318 * is the name of the type defining the constructor. 4870 * is the name of the type defining the constructor.
4319 * 4871 *
4320 * This method assumes that the instance creation was tested to be 'new' 4872 * This method assumes that the instance creation was tested to be 'new'
4321 * before being called. 4873 * before being called.
4322 * 4874 *
4323 * See [StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR]. 4875 * See [StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR].
4324 */ 4876 */
4325 bool _checkForNewWithUndefinedConstructor( 4877 void _checkForNewWithUndefinedConstructor(
4326 InstanceCreationExpression expression, 4878 InstanceCreationExpression expression,
4327 ConstructorName constructorName, 4879 ConstructorName constructorName,
4328 TypeName typeName) { 4880 TypeName typeName) {
4329 // OK if resolved 4881 // OK if resolved
4330 if (expression.staticElement != null) { 4882 if (expression.staticElement != null) {
4331 return false; 4883 return;
4332 } 4884 }
4333 DartType type = typeName.type; 4885 DartType type = typeName.type;
4334 if (type is InterfaceType) { 4886 if (type is InterfaceType) {
4335 ClassElement element = type.element; 4887 ClassElement element = type.element;
4336 if (element != null && element.isEnum) { 4888 if (element != null && element.isEnum) {
4337 // We have already reported the error. 4889 // We have already reported the error.
4338 return false; 4890 return;
4339 } 4891 }
4340 } 4892 }
4341 // prepare class name 4893 // prepare class name
4342 Identifier className = typeName.name; 4894 Identifier className = typeName.name;
4343 // report as named or default constructor absence 4895 // report as named or default constructor absence
4344 SimpleIdentifier name = constructorName.name; 4896 SimpleIdentifier name = constructorName.name;
4345 if (name != null) { 4897 if (name != null) {
4346 _errorReporter.reportErrorForNode( 4898 _errorReporter.reportErrorForNode(
4347 StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, 4899 StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR,
4348 name, 4900 name,
4349 [className, name]); 4901 [className, name]);
4350 } else { 4902 } else {
4351 _errorReporter.reportErrorForNode( 4903 _errorReporter.reportErrorForNode(
4352 StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, 4904 StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
4353 constructorName, 4905 constructorName,
4354 [className]); 4906 [className]);
4355 } 4907 }
4356 return true;
4357 } 4908 }
4358 4909
4359 /** 4910 /**
4360 * Check that if the given class [declaration] implicitly calls default 4911 * Check that if the given class [declaration] implicitly calls default
4361 * constructor of its superclass, there should be such default constructor - 4912 * constructor of its superclass, there should be such default constructor -
4362 * implicit or explicit. 4913 * implicit or explicit.
4363 * 4914 *
4364 * See [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]. 4915 * See [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT].
4365 */ 4916 */
4366 bool _checkForNoDefaultSuperConstructorImplicit( 4917 void _checkForNoDefaultSuperConstructorImplicit(
4367 ClassDeclaration declaration) { 4918 ClassDeclaration declaration) {
4368 // do nothing if mixin errors have already been reported for this class. 4919 // do nothing if mixin errors have already been reported for this class.
4369 ClassElementImpl enclosingClass = _enclosingClass; 4920 if (_enclosingClass.doesMixinLackConstructors) {
4370 if (enclosingClass.doesMixinLackConstructors) { 4921 return;
4371 return false;
4372 } 4922 }
4373 // do nothing if there is explicit constructor 4923 // do nothing if there is explicit constructor
4374 List<ConstructorElement> constructors = _enclosingClass.constructors; 4924 List<ConstructorElement> constructors = _enclosingClass.constructors;
4375 if (!constructors[0].isSynthetic) { 4925 if (!constructors[0].isSynthetic) {
4376 return false; 4926 return;
4377 } 4927 }
4378 // prepare super 4928 // prepare super
4379 InterfaceType superType = _enclosingClass.supertype; 4929 InterfaceType superType = _enclosingClass.supertype;
4380 if (superType == null) { 4930 if (superType == null) {
4381 return false; 4931 return;
4382 } 4932 }
4383 ClassElement superElement = superType.element; 4933 ClassElement superElement = superType.element;
4384 // try to find default generative super constructor 4934 // try to find default generative super constructor
4385 ConstructorElement superUnnamedConstructor = 4935 ConstructorElement superUnnamedConstructor =
4386 superElement.unnamedConstructor; 4936 superElement.unnamedConstructor;
4387 if (superUnnamedConstructor != null) { 4937 if (superUnnamedConstructor != null) {
4388 if (superUnnamedConstructor.isFactory) { 4938 if (superUnnamedConstructor.isFactory) {
4389 _errorReporter.reportErrorForNode( 4939 _errorReporter.reportErrorForNode(
4390 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, 4940 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
4391 declaration.name, 4941 declaration.name,
4392 [superUnnamedConstructor]); 4942 [superUnnamedConstructor]);
4393 return true; 4943 return;
4394 } 4944 }
4395 if (superUnnamedConstructor.isDefaultConstructor && 4945 if (superUnnamedConstructor.isDefaultConstructor &&
4396 _enclosingClass 4946 _enclosingClass
4397 .isSuperConstructorAccessible(superUnnamedConstructor)) { 4947 .isSuperConstructorAccessible(superUnnamedConstructor)) {
4398 return true; 4948 return;
4399 } 4949 }
4400 } 4950 }
4401 // report problem 4951
4402 _errorReporter.reportErrorForNode( 4952 _errorReporter.reportErrorForNode(
4403 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, 4953 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
4404 declaration.name, 4954 declaration.name,
4405 [superType.displayName]); 4955 [superType.displayName]);
4406 return true;
4407 } 4956 }
4408 4957
4409 /** 4958 /**
4410 * Check that the given class declaration overrides all members required by 4959 * Check that the given class declaration overrides all members required by
4411 * its superclasses and interfaces. The [classNameNode] is the 4960 * its superclasses and interfaces. The [classNameNode] is the
4412 * [SimpleIdentifier] to be used if there is a violation, this is either the 4961 * [SimpleIdentifier] to be used if there is a violation, this is either the
4413 * named from the [ClassDeclaration] or from the [ClassTypeAlias]. 4962 * named from the [ClassDeclaration] or from the [ClassTypeAlias].
4414 * 4963 *
4415 * See [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], 4964 * See [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE],
4416 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO], 4965 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO],
4417 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE], 4966 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE],
4418 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR], and 4967 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR], and
4419 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS]. 4968 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS].
4420 */ 4969 */
4421 bool _checkForNonAbstractClassInheritsAbstractMember( 4970 void _checkForNonAbstractClassInheritsAbstractMember(
4422 SimpleIdentifier classNameNode) { 4971 SimpleIdentifier classNameNode) {
4423 if (_enclosingClass.isAbstract) { 4972 if (_enclosingClass.isAbstract) {
4424 return false; 4973 return;
4974 } else if (_enclosingClass.hasNoSuchMethod) {
4975 return;
4425 } 4976 }
4426 // 4977 //
4427 // Store in local sets the set of all method and accessor names 4978 // Store in local sets the set of all method and accessor names
4428 // 4979 //
4429 MethodElement method =
4430 _enclosingClass.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME);
4431 if (method != null) {
4432 // If the enclosing class declares the method noSuchMethod(), then return.
4433 // From Spec: It is a static warning if a concrete class does not have an
4434 // implementation for a method in any of its superinterfaces unless it
4435 // declares its own noSuchMethod method (7.10).
4436 return false;
4437 }
4438 HashSet<ExecutableElement> missingOverrides = 4980 HashSet<ExecutableElement> missingOverrides =
4439 new HashSet<ExecutableElement>(); 4981 new HashSet<ExecutableElement>();
4440 // 4982 //
4441 // Loop through the set of all executable elements declared in the implicit 4983 // Loop through the set of all executable elements declared in the implicit
4442 // interface. 4984 // interface.
4443 // 4985 //
4444 MemberMap membersInheritedFromInterfaces = _inheritanceManager 4986 Map<String, ExecutableElement> membersInheritedFromInterfaces =
4445 .getMapOfMembersInheritedFromInterfaces(_enclosingClass); 4987 _inheritanceManager.getMembersInheritedFromInterfaces(_enclosingClass);
4446 MemberMap membersInheritedFromSuperclasses = _inheritanceManager 4988 Map<String, ExecutableElement> membersInheritedFromSuperclasses =
4447 .getMapOfMembersInheritedFromClasses(_enclosingClass); 4989 _inheritanceManager.getMembersInheritedFromClasses(_enclosingClass);
4448 for (int i = 0; i < membersInheritedFromInterfaces.size; i++) { 4990 for (String memberName in membersInheritedFromInterfaces.keys) {
4449 String memberName = membersInheritedFromInterfaces.getKey(i);
4450 ExecutableElement executableElt = 4991 ExecutableElement executableElt =
4451 membersInheritedFromInterfaces.getValue(i); 4992 membersInheritedFromInterfaces[memberName];
4452 if (memberName == null) { 4993 if (memberName == null) {
4453 break; 4994 break;
4454 } 4995 }
4455 // If the element is not synthetic and can be determined to be defined in 4996 // If the element is not synthetic and can be determined to be defined in
4456 // Object, skip it. 4997 // Object, skip it.
4457 if (executableElt.enclosingElement != null && 4998 if (executableElt.enclosingElement != null &&
4458 (executableElt.enclosingElement as ClassElement).type.isObject) { 4999 (executableElt.enclosingElement as ClassElement).type.isObject) {
4459 continue; 5000 continue;
4460 } 5001 }
4461 // Check to see if some element is in local enclosing class that matches 5002 // Check to see if some element is in local enclosing class that matches
4462 // the name of the required member. 5003 // the name of the required member.
4463 if (_isMemberInClassOrMixin(executableElt, _enclosingClass)) { 5004 if (_isMemberInClassOrMixin(executableElt, _enclosingClass)) {
4464 // We do not have to verify that this implementation of the found method 5005 // We do not have to verify that this implementation of the found method
4465 // matches the required function type: the set of 5006 // matches the required function type: the set of
4466 // StaticWarningCode.INVALID_METHOD_OVERRIDE_* warnings break out the 5007 // StaticWarningCode.INVALID_METHOD_OVERRIDE_* warnings break out the
4467 // different specific situations. 5008 // different specific situations.
4468 continue; 5009 continue;
4469 } 5010 }
4470 // First check to see if this element was declared in the superclass 5011 // First check to see if this element was declared in the superclass
4471 // chain, in which case there is already a concrete implementation. 5012 // chain, in which case there is already a concrete implementation.
4472 ExecutableElement elt = membersInheritedFromSuperclasses.get(memberName); 5013 ExecutableElement elt = membersInheritedFromSuperclasses[memberName];
4473 // Check to see if an element was found in the superclass chain with the 5014 // Check to see if an element was found in the superclass chain with the
4474 // correct name. 5015 // correct name.
4475 if (elt != null) { 5016 if (elt != null) {
4476 // Reference the types, if any are null then continue. 5017 // Reference the types, if any are null then continue.
4477 InterfaceType enclosingType = _enclosingClass.type; 5018 InterfaceType enclosingType = _enclosingClass.type;
4478 FunctionType concreteType = elt.type; 5019 FunctionType concreteType = elt.type;
4479 FunctionType requiredMemberType = executableElt.type; 5020 FunctionType requiredMemberType = executableElt.type;
4480 if (enclosingType == null || 5021 if (enclosingType == null ||
4481 concreteType == null || 5022 concreteType == null ||
4482 requiredMemberType == null) { 5023 requiredMemberType == null) {
4483 continue; 5024 continue;
4484 } 5025 }
4485 // Some element was found in the superclass chain that matches the name 5026 // Some element was found in the superclass chain that matches the name
4486 // of the required member. 5027 // of the required member.
4487 // If it is not abstract and it is the correct one (types match- the 5028 // If it is not abstract and it is the correct one (types match- the
4488 // version of this method that we have has the correct number of 5029 // version of this method that we have has the correct number of
4489 // parameters, etc), then this class has a valid implementation of this 5030 // parameters, etc), then this class has a valid implementation of this
4490 // method, so skip it. 5031 // method, so skip it.
4491 if ((elt is MethodElement && !elt.isAbstract) || 5032 if ((elt is MethodElement && !elt.isAbstract) ||
4492 (elt is PropertyAccessorElement && !elt.isAbstract)) { 5033 (elt is PropertyAccessorElement && !elt.isAbstract)) {
4493 // Since we are comparing two function types, we need to do the 5034 // Since we are comparing two function types, we need to do the
4494 // appropriate type substitutions first (). 5035 // appropriate type substitutions first ().
4495 FunctionType foundConcreteFT = _inheritanceManager 5036 FunctionType foundConcreteFT = _inheritanceManager
4496 .substituteTypeArgumentsInMemberFromInheritance( 5037 .substituteTypeArgumentsInMemberFromInheritance(
4497 concreteType, memberName, enclosingType); 5038 concreteType, memberName, enclosingType);
4498 FunctionType requiredMemberFT = _inheritanceManager 5039 FunctionType requiredMemberFT = _inheritanceManager
4499 .substituteTypeArgumentsInMemberFromInheritance( 5040 .substituteTypeArgumentsInMemberFromInheritance(
4500 requiredMemberType, memberName, enclosingType); 5041 requiredMemberType, memberName, enclosingType);
4501 if (_typeSystem.isSubtypeOf(foundConcreteFT, requiredMemberFT)) { 5042 foundConcreteFT = _typeSystem.functionTypeToConcreteType(
5043 _typeProvider, foundConcreteFT);
5044 requiredMemberFT = _typeSystem.functionTypeToConcreteType(
5045 _typeProvider, requiredMemberFT);
5046
5047 // Strong mode does override checking for types in CodeChecker, so
5048 // we can skip it here. Doing it here leads to unnecessary duplicate
5049 // error messages in subclasses that inherit from one that has an
5050 // override error.
5051 //
5052 // See: https://github.com/dart-lang/sdk/issues/25232
5053 if (_options.strongMode ||
5054 _typeSystem.isSubtypeOf(foundConcreteFT, requiredMemberFT)) {
4502 continue; 5055 continue;
4503 } 5056 }
4504 } 5057 }
4505 } 5058 }
4506 // The not qualifying concrete executable element was found, add it to the 5059 // The not qualifying concrete executable element was found, add it to the
4507 // list. 5060 // list.
4508 missingOverrides.add(executableElt); 5061 missingOverrides.add(executableElt);
4509 } 5062 }
4510 // Now that we have the set of missing overrides, generate a warning on this 5063 // Now that we have the set of missing overrides, generate a warning on this
4511 // class. 5064 // class.
4512 int missingOverridesSize = missingOverrides.length; 5065 int missingOverridesSize = missingOverrides.length;
4513 if (missingOverridesSize == 0) { 5066 if (missingOverridesSize == 0) {
4514 return false; 5067 return;
4515 } 5068 }
4516 List<ExecutableElement> missingOverridesArray = 5069 List<ExecutableElement> missingOverridesArray =
4517 new List.from(missingOverrides); 5070 new List.from(missingOverrides);
4518 List<String> stringMembersArrayListSet = new List<String>(); 5071 List<String> stringMembersArrayListSet = new List<String>();
4519 for (int i = 0; i < missingOverridesArray.length; i++) { 5072 for (int i = 0; i < missingOverridesArray.length; i++) {
4520 String newStrMember; 5073 String newStrMember;
4521 Element enclosingElement = missingOverridesArray[i].enclosingElement; 5074 ExecutableElement element = missingOverridesArray[i];
5075 Element enclosingElement = element.enclosingElement;
4522 String prefix = StringUtilities.EMPTY; 5076 String prefix = StringUtilities.EMPTY;
4523 if (missingOverridesArray[i] is PropertyAccessorElement) { 5077 if (element is PropertyAccessorElement) {
4524 PropertyAccessorElement propertyAccessorElement = 5078 if (element.isGetter) {
4525 missingOverridesArray[i] as PropertyAccessorElement;
4526 if (propertyAccessorElement.isGetter) {
4527 prefix = _GETTER_SPACE; 5079 prefix = _GETTER_SPACE;
4528 // "getter " 5080 // "getter "
4529 } else { 5081 } else {
4530 prefix = _SETTER_SPACE; 5082 prefix = _SETTER_SPACE;
4531 // "setter " 5083 // "setter "
4532 } 5084 }
4533 } 5085 }
4534 if (enclosingElement != null) { 5086 if (enclosingElement != null) {
4535 newStrMember = 5087 newStrMember =
4536 "$prefix'${enclosingElement.displayName}.${missingOverridesArray[i]. displayName}'"; 5088 "$prefix'${enclosingElement.displayName}.${element.displayName}'";
4537 } else { 5089 } else {
4538 newStrMember = "$prefix'${missingOverridesArray[i].displayName}'"; 5090 newStrMember = "$prefix'${element.displayName}'";
4539 } 5091 }
4540 stringMembersArrayListSet.add(newStrMember); 5092 stringMembersArrayListSet.add(newStrMember);
4541 } 5093 }
4542 List<String> stringMembersArray = new List.from(stringMembersArrayListSet); 5094 List<String> stringMembersArray = new List.from(stringMembersArrayListSet);
5095 stringMembersArray.sort();
4543 AnalysisErrorWithProperties analysisError; 5096 AnalysisErrorWithProperties analysisError;
4544 if (stringMembersArray.length == 1) { 5097 if (stringMembersArray.length == 1) {
4545 analysisError = _errorReporter.newErrorWithProperties( 5098 analysisError = _errorReporter.newErrorWithProperties(
4546 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, 5099 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE,
4547 classNameNode, 5100 classNameNode,
4548 [stringMembersArray[0]]); 5101 [stringMembersArray[0]]);
4549 } else if (stringMembersArray.length == 2) { 5102 } else if (stringMembersArray.length == 2) {
4550 analysisError = _errorReporter.newErrorWithProperties( 5103 analysisError = _errorReporter.newErrorWithProperties(
4551 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, 5104 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO,
4552 classNameNode, 5105 classNameNode,
(...skipping 10 matching lines...) Expand all
4563 analysisError = _errorReporter.newErrorWithProperties( 5116 analysisError = _errorReporter.newErrorWithProperties(
4564 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, 5117 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR,
4565 classNameNode, [ 5118 classNameNode, [
4566 stringMembersArray[0], 5119 stringMembersArray[0],
4567 stringMembersArray[1], 5120 stringMembersArray[1],
4568 stringMembersArray[2], 5121 stringMembersArray[2],
4569 stringMembersArray[3] 5122 stringMembersArray[3]
4570 ]); 5123 ]);
4571 } else { 5124 } else {
4572 analysisError = _errorReporter.newErrorWithProperties( 5125 analysisError = _errorReporter.newErrorWithProperties(
4573 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLU S, 5126 StaticWarningCode
4574 classNameNode, [ 5127 .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS,
4575 stringMembersArray[0], 5128 classNameNode,
4576 stringMembersArray[1], 5129 [
4577 stringMembersArray[2], 5130 stringMembersArray[0],
4578 stringMembersArray[3], 5131 stringMembersArray[1],
4579 stringMembersArray.length - 4 5132 stringMembersArray[2],
4580 ]); 5133 stringMembersArray[3],
5134 stringMembersArray.length - 4
5135 ]);
4581 } 5136 }
4582 analysisError.setProperty( 5137 analysisError.setProperty(
4583 ErrorProperty.UNIMPLEMENTED_METHODS, missingOverridesArray); 5138 ErrorProperty.UNIMPLEMENTED_METHODS, missingOverridesArray);
4584 _errorReporter.reportError(analysisError); 5139 _errorReporter.reportError(analysisError);
4585 return true;
4586 } 5140 }
4587 5141
4588 /** 5142 /**
4589 * Check to ensure that the [condition] is of type bool, are. Otherwise an 5143 * Check to ensure that the [condition] is of type bool, are. Otherwise an
4590 * error is reported on the expression. 5144 * error is reported on the expression.
4591 * 5145 *
4592 * See [StaticTypeWarningCode.NON_BOOL_CONDITION]. 5146 * See [StaticTypeWarningCode.NON_BOOL_CONDITION].
4593 */ 5147 */
4594 bool _checkForNonBoolCondition(Expression condition) { 5148 void _checkForNonBoolCondition(Expression condition) {
4595 DartType conditionType = getStaticType(condition); 5149 DartType conditionType = getStaticType(condition);
4596 if (conditionType != null && 5150 if (conditionType != null &&
4597 !_typeSystem.isAssignableTo(conditionType, _boolType)) { 5151 !_typeSystem.isAssignableTo(conditionType, _boolType)) {
4598 _errorReporter.reportErrorForNode( 5152 _errorReporter.reportErrorForNode(
4599 StaticTypeWarningCode.NON_BOOL_CONDITION, condition); 5153 StaticTypeWarningCode.NON_BOOL_CONDITION, condition);
4600 return true;
4601 } 5154 }
4602 return false;
4603 } 5155 }
4604 5156
4605 /** 5157 /**
4606 * Verify that the given assert [statement] has either a 'bool' or 5158 * Verify that the given assert [statement] has either a 'bool' or
4607 * '() -> bool' input. 5159 * '() -> bool' input.
4608 * 5160 *
4609 * See [StaticTypeWarningCode.NON_BOOL_EXPRESSION]. 5161 * See [StaticTypeWarningCode.NON_BOOL_EXPRESSION].
4610 */ 5162 */
4611 bool _checkForNonBoolExpression(AssertStatement statement) { 5163 void _checkForNonBoolExpression(AssertStatement statement) {
4612 Expression expression = statement.condition; 5164 Expression expression = statement.condition;
4613 DartType type = getStaticType(expression); 5165 DartType type = getStaticType(expression);
4614 if (type is InterfaceType) { 5166 if (type is InterfaceType) {
4615 if (!_typeSystem.isAssignableTo(type, _boolType)) { 5167 if (!_typeSystem.isAssignableTo(type, _boolType)) {
4616 _errorReporter.reportErrorForNode( 5168 _errorReporter.reportErrorForNode(
4617 StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression); 5169 StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression);
4618 return true;
4619 } 5170 }
4620 } else if (type is FunctionType) { 5171 } else if (type is FunctionType) {
4621 FunctionType functionType = type; 5172 if (type.typeArguments.length == 0 &&
4622 if (functionType.typeArguments.length == 0 && 5173 !_typeSystem.isAssignableTo(type.returnType, _boolType)) {
4623 !_typeSystem.isAssignableTo(functionType.returnType, _boolType)) {
4624 _errorReporter.reportErrorForNode( 5174 _errorReporter.reportErrorForNode(
4625 StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression); 5175 StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression);
4626 return true;
4627 } 5176 }
4628 } 5177 }
4629 return false;
4630 } 5178 }
4631 5179
4632 /** 5180 /**
4633 * Checks to ensure that the given [expression] is assignable to bool. 5181 * Checks to ensure that the given [expression] is assignable to bool.
4634 * 5182 *
4635 * See [StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION]. 5183 * See [StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION].
4636 */ 5184 */
4637 bool _checkForNonBoolNegationExpression(Expression expression) { 5185 void _checkForNonBoolNegationExpression(Expression expression) {
4638 DartType conditionType = getStaticType(expression); 5186 DartType conditionType = getStaticType(expression);
4639 if (conditionType != null && 5187 if (conditionType != null &&
4640 !_typeSystem.isAssignableTo(conditionType, _boolType)) { 5188 !_typeSystem.isAssignableTo(conditionType, _boolType)) {
4641 _errorReporter.reportErrorForNode( 5189 _errorReporter.reportErrorForNode(
4642 StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression); 5190 StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression);
4643 return true;
4644 } 5191 }
4645 return false;
4646 } 5192 }
4647 5193
4648 /** 5194 /**
4649 * Verify the given map [literal] either: 5195 * Verify the given map [literal] either:
4650 * * has `const modifier` 5196 * * has `const modifier`
4651 * * has explicit type arguments 5197 * * has explicit type arguments
4652 * * is not start of the statement 5198 * * is not start of the statement
4653 * 5199 *
4654 * See [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]. 5200 * See [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT].
4655 */ 5201 */
4656 bool _checkForNonConstMapAsExpressionStatement(MapLiteral literal) { 5202 void _checkForNonConstMapAsExpressionStatement(MapLiteral literal) {
4657 // "const" 5203 // "const"
4658 if (literal.constKeyword != null) { 5204 if (literal.constKeyword != null) {
4659 return false; 5205 return;
4660 } 5206 }
4661 // has type arguments 5207 // has type arguments
4662 if (literal.typeArguments != null) { 5208 if (literal.typeArguments != null) {
4663 return false; 5209 return;
4664 } 5210 }
4665 // prepare statement 5211 // prepare statement
4666 Statement statement = 5212 Statement statement =
4667 literal.getAncestor((node) => node is ExpressionStatement); 5213 literal.getAncestor((node) => node is ExpressionStatement);
4668 if (statement == null) { 5214 if (statement == null) {
4669 return false; 5215 return;
4670 } 5216 }
4671 // OK, statement does not start with map 5217 // OK, statement does not start with map
4672 if (!identical(statement.beginToken, literal.beginToken)) { 5218 if (!identical(statement.beginToken, literal.beginToken)) {
4673 return false; 5219 return;
4674 } 5220 }
4675 // report problem 5221
4676 _errorReporter.reportErrorForNode( 5222 _errorReporter.reportErrorForNode(
4677 CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, literal); 5223 CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, literal);
4678 return true;
4679 } 5224 }
4680 5225
4681 /** 5226 /**
4682 * Verify that the given method [declaration] of operator `[]=`, has `void` 5227 * Verify that the given method [declaration] of operator `[]=`, has `void`
4683 * return type. 5228 * return type.
4684 * 5229 *
4685 * See [StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR]. 5230 * See [StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR].
4686 */ 5231 */
4687 bool _checkForNonVoidReturnTypeForOperator(MethodDeclaration declaration) { 5232 void _checkForNonVoidReturnTypeForOperator(MethodDeclaration declaration) {
4688 // check that []= operator 5233 // check that []= operator
4689 SimpleIdentifier name = declaration.name; 5234 SimpleIdentifier name = declaration.name;
4690 if (name.name != "[]=") { 5235 if (name.name != "[]=") {
4691 return false; 5236 return;
4692 } 5237 }
4693 // check return type 5238 // check return type
4694 TypeName typeName = declaration.returnType; 5239 TypeName typeName = declaration.returnType;
4695 if (typeName != null) { 5240 if (typeName != null) {
4696 DartType type = typeName.type; 5241 DartType type = typeName.type;
4697 if (type != null && !type.isVoid) { 5242 if (type != null && !type.isVoid) {
4698 _errorReporter.reportErrorForNode( 5243 _errorReporter.reportErrorForNode(
4699 StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, typeName); 5244 StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, typeName);
4700 } 5245 }
4701 } 5246 }
4702 // no warning
4703 return false;
4704 } 5247 }
4705 5248
4706 /** 5249 /**
4707 * Verify the [typeName], used as the return type of a setter, is valid 5250 * Verify the [typeName], used as the return type of a setter, is valid
4708 * (either `null` or the type 'void'). 5251 * (either `null` or the type 'void').
4709 * 5252 *
4710 * See [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER]. 5253 * See [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER].
4711 */ 5254 */
4712 bool _checkForNonVoidReturnTypeForSetter(TypeName typeName) { 5255 void _checkForNonVoidReturnTypeForSetter(TypeName typeName) {
4713 if (typeName != null) { 5256 if (typeName != null) {
4714 DartType type = typeName.type; 5257 DartType type = typeName.type;
4715 if (type != null && !type.isVoid) { 5258 if (type != null && !type.isVoid) {
4716 _errorReporter.reportErrorForNode( 5259 _errorReporter.reportErrorForNode(
4717 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, typeName); 5260 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, typeName);
4718 } 5261 }
4719 } 5262 }
4720 return false;
4721 } 5263 }
4722 5264
4723 /** 5265 /**
4724 * Verify the given operator-method [declaration], does not have an optional 5266 * Verify the given operator-method [declaration], does not have an optional
4725 * parameter. This method assumes that the method declaration was tested to be 5267 * parameter. This method assumes that the method declaration was tested to be
4726 * an operator declaration before being called. 5268 * an operator declaration before being called.
4727 * 5269 *
4728 * See [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]. 5270 * See [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR].
4729 */ 5271 */
4730 bool _checkForOptionalParameterInOperator(MethodDeclaration declaration) { 5272 void _checkForOptionalParameterInOperator(MethodDeclaration declaration) {
4731 FormalParameterList parameterList = declaration.parameters; 5273 FormalParameterList parameterList = declaration.parameters;
4732 if (parameterList == null) { 5274 if (parameterList == null) {
4733 return false; 5275 return;
4734 } 5276 }
4735 bool foundError = false; 5277
4736 NodeList<FormalParameter> formalParameters = parameterList.parameters; 5278 NodeList<FormalParameter> formalParameters = parameterList.parameters;
4737 for (FormalParameter formalParameter in formalParameters) { 5279 for (FormalParameter formalParameter in formalParameters) {
4738 if (formalParameter.kind.isOptional) { 5280 if (formalParameter.kind.isOptional) {
4739 _errorReporter.reportErrorForNode( 5281 _errorReporter.reportErrorForNode(
4740 CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, 5282 CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR,
4741 formalParameter); 5283 formalParameter);
4742 foundError = true;
4743 } 5284 }
4744 } 5285 }
4745 return foundError;
4746 } 5286 }
4747 5287
4748 /** 5288 /**
4749 * Check that the given named optional [parameter] does not begin with '_'. 5289 * Check that the given named optional [parameter] does not begin with '_'.
4750 * 5290 *
4751 * See [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]. 5291 * See [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER].
4752 */ 5292 */
4753 bool _checkForPrivateOptionalParameter(FormalParameter parameter) { 5293 void _checkForPrivateOptionalParameter(FormalParameter parameter) {
4754 // should be named parameter 5294 // should be named parameter
4755 if (parameter.kind != ParameterKind.NAMED) { 5295 if (parameter.kind != ParameterKind.NAMED) {
4756 return false; 5296 return;
4757 } 5297 }
4758 // name should start with '_' 5298 // name should start with '_'
4759 SimpleIdentifier name = parameter.identifier; 5299 SimpleIdentifier name = parameter.identifier;
4760 if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) { 5300 if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) {
4761 return false; 5301 return;
4762 } 5302 }
4763 // report problem 5303
4764 _errorReporter.reportErrorForNode( 5304 _errorReporter.reportErrorForNode(
4765 CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, parameter); 5305 CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, parameter);
4766 return true;
4767 } 5306 }
4768 5307
4769 /** 5308 /**
4770 * Check whether the given constructor [declaration] is the redirecting 5309 * Check whether the given constructor [declaration] is the redirecting
4771 * generative constructor and references itself directly or indirectly. The 5310 * generative constructor and references itself directly or indirectly. The
4772 * [constructorElement] is the constructor element. 5311 * [constructorElement] is the constructor element.
4773 * 5312 *
4774 * See [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]. 5313 * See [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT].
4775 */ 5314 */
4776 bool _checkForRecursiveConstructorRedirect(ConstructorDeclaration declaration, 5315 void _checkForRecursiveConstructorRedirect(ConstructorDeclaration declaration,
4777 ConstructorElement constructorElement) { 5316 ConstructorElement constructorElement) {
4778 // we check generative constructor here 5317 // we check generative constructor here
4779 if (declaration.factoryKeyword != null) { 5318 if (declaration.factoryKeyword != null) {
4780 return false; 5319 return;
4781 } 5320 }
4782 // try to find redirecting constructor invocation and analyzer it for 5321 // try to find redirecting constructor invocation and analyze it for
4783 // recursion 5322 // recursion
4784 for (ConstructorInitializer initializer in declaration.initializers) { 5323 for (ConstructorInitializer initializer in declaration.initializers) {
4785 if (initializer is RedirectingConstructorInvocation) { 5324 if (initializer is RedirectingConstructorInvocation) {
4786 // OK if no cycle 5325 if (_hasRedirectingFactoryConstructorCycle(constructorElement)) {
4787 if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) { 5326 _errorReporter.reportErrorForNode(
4788 return false; 5327 CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer);
4789 } 5328 }
4790 // report error 5329 return;
4791 _errorReporter.reportErrorForNode(
4792 CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer);
4793 return true;
4794 } 5330 }
4795 } 5331 }
4796 // OK, no redirecting constructor invocation
4797 return false;
4798 } 5332 }
4799 5333
4800 /** 5334 /**
4801 * Check whether the given constructor [declaration] has redirected 5335 * Check whether the given constructor [declaration] has redirected
4802 * constructor and references itself directly or indirectly. The 5336 * constructor and references itself directly or indirectly. The
4803 * constructor [element] is the element introduced by the declaration. 5337 * constructor [element] is the element introduced by the declaration.
4804 * 5338 *
4805 * See [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]. 5339 * See [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT].
4806 */ 5340 */
4807 bool _checkForRecursiveFactoryRedirect( 5341 bool _checkForRecursiveFactoryRedirect(
(...skipping 15 matching lines...) Expand all
4823 return true; 5357 return true;
4824 } 5358 }
4825 5359
4826 /** 5360 /**
4827 * Check that the class [element] is not a superinterface to itself. 5361 * Check that the class [element] is not a superinterface to itself.
4828 * 5362 *
4829 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], 5363 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE],
4830 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], a nd 5364 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], a nd
4831 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS] . 5365 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS] .
4832 */ 5366 */
4833 bool _checkForRecursiveInterfaceInheritance(ClassElement element) { 5367 void _checkForRecursiveInterfaceInheritance(ClassElement element) {
4834 if (element == null) { 5368 if (element == null) {
4835 return false; 5369 return;
4836 } 5370 }
4837 return _safeCheckForRecursiveInterfaceInheritance( 5371
4838 element, new List<ClassElement>()); 5372 _safeCheckForRecursiveInterfaceInheritance(element, <ClassElement>[]);
4839 } 5373 }
4840 5374
4841 /** 5375 /**
4842 * Check that the given constructor [declaration] has a valid combination of 5376 * Check that the given constructor [declaration] has a valid combination of
4843 * redirected constructor invocation(s), super constructor invocations and 5377 * redirected constructor invocation(s), super constructor invocations and
4844 * field initializers. 5378 * field initializers.
4845 * 5379 *
4846 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR] , 5380 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR] ,
4847 * [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR], 5381 * [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR],
4848 * [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS], 5382 * [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS],
4849 * [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR], and 5383 * [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR], and
4850 * [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR]. 5384 * [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR].
4851 */ 5385 */
4852 bool _checkForRedirectingConstructorErrorCodes( 5386 void _checkForRedirectingConstructorErrorCodes(
4853 ConstructorDeclaration declaration) { 5387 ConstructorDeclaration declaration) {
4854 bool errorReported = false;
4855 //
4856 // Check for default values in the parameters 5388 // Check for default values in the parameters
4857 //
4858 ConstructorName redirectedConstructor = declaration.redirectedConstructor; 5389 ConstructorName redirectedConstructor = declaration.redirectedConstructor;
4859 if (redirectedConstructor != null) { 5390 if (redirectedConstructor != null) {
4860 for (FormalParameter parameter in declaration.parameters.parameters) { 5391 for (FormalParameter parameter in declaration.parameters.parameters) {
4861 if (parameter is DefaultFormalParameter && 5392 if (parameter is DefaultFormalParameter &&
4862 parameter.defaultValue != null) { 5393 parameter.defaultValue != null) {
4863 _errorReporter.reportErrorForNode( 5394 _errorReporter.reportErrorForNode(
4864 CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUC TOR, 5395 CompileTimeErrorCode
5396 .DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
4865 parameter.identifier); 5397 parameter.identifier);
4866 errorReported = true;
4867 } 5398 }
4868 } 5399 }
4869 } 5400 }
4870 // check if there are redirected invocations 5401 // check if there are redirected invocations
4871 int numRedirections = 0; 5402 int numRedirections = 0;
4872 for (ConstructorInitializer initializer in declaration.initializers) { 5403 for (ConstructorInitializer initializer in declaration.initializers) {
4873 if (initializer is RedirectingConstructorInvocation) { 5404 if (initializer is RedirectingConstructorInvocation) {
4874 if (numRedirections > 0) { 5405 if (numRedirections > 0) {
4875 _errorReporter.reportErrorForNode( 5406 _errorReporter.reportErrorForNode(
4876 CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS, 5407 CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
4877 initializer); 5408 initializer);
4878 errorReported = true;
4879 } 5409 }
4880 if (declaration.factoryKeyword == null) { 5410 if (declaration.factoryKeyword == null) {
4881 RedirectingConstructorInvocation invocation = initializer; 5411 RedirectingConstructorInvocation invocation = initializer;
4882 ConstructorElement redirectingElement = invocation.staticElement; 5412 ConstructorElement redirectingElement = invocation.staticElement;
4883 if (redirectingElement == null) { 5413 if (redirectingElement == null) {
4884 String enclosingTypeName = _enclosingClass.displayName; 5414 String enclosingTypeName = _enclosingClass.displayName;
4885 String constructorStrName = enclosingTypeName; 5415 String constructorStrName = enclosingTypeName;
4886 if (invocation.constructorName != null) { 5416 if (invocation.constructorName != null) {
4887 constructorStrName += ".${invocation.constructorName.name}"; 5417 constructorStrName += ".${invocation.constructorName.name}";
4888 } 5418 }
4889 _errorReporter.reportErrorForNode( 5419 _errorReporter.reportErrorForNode(
4890 CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR, 5420 CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
4891 invocation, 5421 invocation,
4892 [constructorStrName, enclosingTypeName]); 5422 [constructorStrName, enclosingTypeName]);
4893 } else { 5423 } else {
4894 if (redirectingElement.isFactory) { 5424 if (redirectingElement.isFactory) {
4895 _errorReporter.reportErrorForNode( 5425 _errorReporter.reportErrorForNode(
4896 CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CON STRUCTOR, 5426 CompileTimeErrorCode
5427 .REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
4897 initializer); 5428 initializer);
4898 } 5429 }
4899 } 5430 }
4900 } 5431 }
4901 numRedirections++; 5432 numRedirections++;
4902 } 5433 }
4903 } 5434 }
4904 // check for other initializers 5435 // check for other initializers
4905 if (numRedirections > 0) { 5436 if (numRedirections > 0) {
4906 for (ConstructorInitializer initializer in declaration.initializers) { 5437 for (ConstructorInitializer initializer in declaration.initializers) {
4907 if (initializer is SuperConstructorInvocation) { 5438 if (initializer is SuperConstructorInvocation) {
4908 _errorReporter.reportErrorForNode( 5439 _errorReporter.reportErrorForNode(
4909 CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, 5440 CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
4910 initializer); 5441 initializer);
4911 errorReported = true;
4912 } 5442 }
4913 if (initializer is ConstructorFieldInitializer) { 5443 if (initializer is ConstructorFieldInitializer) {
4914 _errorReporter.reportErrorForNode( 5444 _errorReporter.reportErrorForNode(
4915 CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, 5445 CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
4916 initializer); 5446 initializer);
4917 errorReported = true;
4918 } 5447 }
4919 } 5448 }
4920 } 5449 }
4921 // done
4922 return errorReported;
4923 } 5450 }
4924 5451
4925 /** 5452 /**
4926 * Check whether the given constructor [declaration] has redirected 5453 * Check whether the given constructor [declaration] has redirected
4927 * constructor and references itself directly or indirectly. The 5454 * constructor and references itself directly or indirectly. The
4928 * constructor [element] is the element introduced by the declaration. 5455 * constructor [element] is the element introduced by the declaration.
4929 * 5456 *
4930 * See [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]. 5457 * See [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR].
4931 */ 5458 */
4932 bool _checkForRedirectToNonConstConstructor( 5459 void _checkForRedirectToNonConstConstructor(
4933 ConstructorDeclaration declaration, ConstructorElement element) { 5460 ConstructorDeclaration declaration, ConstructorElement element) {
4934 // prepare redirected constructor 5461 // prepare redirected constructor
4935 ConstructorName redirectedConstructorNode = 5462 ConstructorName redirectedConstructorNode =
4936 declaration.redirectedConstructor; 5463 declaration.redirectedConstructor;
4937 if (redirectedConstructorNode == null) { 5464 if (redirectedConstructorNode == null) {
4938 return false; 5465 return;
4939 } 5466 }
4940 // prepare element 5467 // prepare element
4941 if (element == null) { 5468 if (element == null) {
4942 return false; 5469 return;
4943 } 5470 }
4944 // OK, it is not 'const' 5471 // OK, it is not 'const'
4945 if (!element.isConst) { 5472 if (!element.isConst) {
4946 return false; 5473 return;
4947 } 5474 }
4948 // prepare redirected constructor 5475 // prepare redirected constructor
4949 ConstructorElement redirectedConstructor = element.redirectedConstructor; 5476 ConstructorElement redirectedConstructor = element.redirectedConstructor;
4950 if (redirectedConstructor == null) { 5477 if (redirectedConstructor == null) {
4951 return false; 5478 return;
4952 } 5479 }
4953 // OK, it is also 'const' 5480 // OK, it is also 'const'
4954 if (redirectedConstructor.isConst) { 5481 if (redirectedConstructor.isConst) {
4955 return false; 5482 return;
4956 } 5483 }
4957 // report error 5484
4958 _errorReporter.reportErrorForNode( 5485 _errorReporter.reportErrorForNode(
4959 CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, 5486 CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR,
4960 redirectedConstructorNode); 5487 redirectedConstructorNode);
4961 return true; 5488 }
5489
5490 void _checkForReferenceBeforeDeclaration(SimpleIdentifier node) {
5491 if (!node.inDeclarationContext() &&
5492 _hiddenElements != null &&
5493 _hiddenElements.contains(node.staticElement)) {
5494 _errorReporter.reportErrorForNode(
5495 CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION,
5496 node,
5497 [node.name]);
5498 }
4962 } 5499 }
4963 5500
4964 /** 5501 /**
4965 * Check that the given rethrow [expression] is inside of a catch clause. 5502 * Check that the given rethrow [expression] is inside of a catch clause.
4966 * 5503 *
4967 * See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]. 5504 * See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH].
4968 */ 5505 */
4969 bool _checkForRethrowOutsideCatch(RethrowExpression expression) { 5506 void _checkForRethrowOutsideCatch(RethrowExpression expression) {
4970 if (!_isInCatchClause) { 5507 if (!_isInCatchClause) {
4971 _errorReporter.reportErrorForNode( 5508 _errorReporter.reportErrorForNode(
4972 CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, expression); 5509 CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, expression);
4973 return true;
4974 } 5510 }
4975 return false;
4976 } 5511 }
4977 5512
4978 /** 5513 /**
4979 * Check that if the the given constructor [declaration] is generative, then 5514 * Check that if the given constructor [declaration] is generative, then
4980 * it does not have an expression function body. 5515 * it does not have an expression function body.
4981 * 5516 *
4982 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]. 5517 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR].
4983 */ 5518 */
4984 bool _checkForReturnInGenerativeConstructor( 5519 void _checkForReturnInGenerativeConstructor(
4985 ConstructorDeclaration declaration) { 5520 ConstructorDeclaration declaration) {
4986 // ignore factory 5521 // ignore factory
4987 if (declaration.factoryKeyword != null) { 5522 if (declaration.factoryKeyword != null) {
4988 return false; 5523 return;
4989 } 5524 }
4990 // block body (with possible return statement) is checked elsewhere 5525 // block body (with possible return statement) is checked elsewhere
4991 FunctionBody body = declaration.body; 5526 FunctionBody body = declaration.body;
4992 if (body is! ExpressionFunctionBody) { 5527 if (body is! ExpressionFunctionBody) {
4993 return false; 5528 return;
4994 } 5529 }
4995 // report error 5530
4996 _errorReporter.reportErrorForNode( 5531 _errorReporter.reportErrorForNode(
4997 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body); 5532 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body);
4998 return true;
4999 } 5533 }
5000 5534
5001 /** 5535 /**
5002 * Check that a type mis-match between the type of the [returnExpression] and 5536 * Check that a type mis-match between the type of the [returnExpression] and
5003 * the [expectedReturnType] by the enclosing method or function. 5537 * the [expectedReturnType] by the enclosing method or function.
5004 * 5538 *
5005 * This method is called both by [_checkForAllReturnStatementErrorCodes] 5539 * This method is called both by [_checkForAllReturnStatementErrorCodes]
5006 * and [visitExpressionFunctionBody]. 5540 * and [visitExpressionFunctionBody].
5007 * 5541 *
5008 * See [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. 5542 * See [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE].
5009 */ 5543 */
5010 bool _checkForReturnOfInvalidType( 5544 void _checkForReturnOfInvalidType(
5011 Expression returnExpression, DartType expectedReturnType) { 5545 Expression returnExpression, DartType expectedReturnType) {
5012 if (_enclosingFunction == null) { 5546 if (_enclosingFunction == null) {
5013 return false; 5547 return;
5014 } 5548 }
5015 if (_inGenerator) { 5549 if (_inGenerator) {
5016 // "return expression;" is disallowed in generators, but this is checked 5550 // "return expression;" is disallowed in generators, but this is checked
5017 // elsewhere. Bare "return" is always allowed in generators regardless 5551 // elsewhere. Bare "return" is always allowed in generators regardless
5018 // of the return type. So no need to do any further checking. 5552 // of the return type. So no need to do any further checking.
5019 return false; 5553 return;
5020 } 5554 }
5021 DartType staticReturnType = _computeReturnTypeForMethod(returnExpression); 5555 DartType staticReturnType = _computeReturnTypeForMethod(returnExpression);
5022 if (expectedReturnType.isVoid) { 5556 if (expectedReturnType.isVoid) {
5023 if (staticReturnType.isVoid || 5557 if (staticReturnType.isVoid ||
5024 staticReturnType.isDynamic || 5558 staticReturnType.isDynamic ||
5025 staticReturnType.isBottom) { 5559 staticReturnType.isBottom) {
5026 return false; 5560 return;
5027 } 5561 }
5028 _errorReporter.reportTypeErrorForNode( 5562 _errorReporter.reportTypeErrorForNode(
5029 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [ 5563 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [
5030 staticReturnType, 5564 staticReturnType,
5031 expectedReturnType, 5565 expectedReturnType,
5032 _enclosingFunction.displayName 5566 _enclosingFunction.displayName
5033 ]); 5567 ]);
5034 return true; 5568 return;
5035 } 5569 }
5036 if (_typeSystem.isAssignableTo(staticReturnType, expectedReturnType)) { 5570 if (_expressionIsAssignableAtType(
5037 return false; 5571 returnExpression, staticReturnType, expectedReturnType)) {
5572 return;
5038 } 5573 }
5039 _errorReporter.reportTypeErrorForNode( 5574 _errorReporter.reportTypeErrorForNode(
5040 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, 5575 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
5041 returnExpression, 5576 returnExpression,
5042 [staticReturnType, expectedReturnType, _enclosingFunction.displayName]); 5577 [staticReturnType, expectedReturnType, _enclosingFunction.displayName]);
5043 return true; 5578
5044 // TODO(brianwilkerson) Define a hint corresponding to the warning and 5579 // TODO(brianwilkerson) Define a hint corresponding to the warning and
5045 // report it if appropriate. 5580 // report it if appropriate.
5046 // Type propagatedReturnType = returnExpression.getPropagatedType(); 5581 // Type propagatedReturnType = returnExpression.getPropagatedType();
5047 // boolean isPropagatedAssignable = propagatedReturnType.isAssignableTo(e xpectedReturnType); 5582 // boolean isPropagatedAssignable = propagatedReturnType.isAssignableTo(e xpectedReturnType);
5048 // if (isStaticAssignable || isPropagatedAssignable) { 5583 // if (isStaticAssignable || isPropagatedAssignable) {
5049 // return false; 5584 // return false;
5050 // } 5585 // }
5051 // errorReporter.reportTypeErrorForNode( 5586 // errorReporter.reportTypeErrorForNode(
5052 // StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, 5587 // StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
5053 // returnExpression, 5588 // returnExpression,
5054 // staticReturnType, 5589 // staticReturnType,
5055 // expectedReturnType, 5590 // expectedReturnType,
5056 // enclosingFunction.getDisplayName()); 5591 // enclosingFunction.getDisplayName());
5057 // return true; 5592 // return true;
5058 } 5593 }
5059 5594
5060 /** 5595 /**
5061 * Check the given [typeReference] and that the [name] is not the reference to 5596 * Check the given [typeReference] and that the [name] is not a reference to
5062 * an instance member. 5597 * an instance member.
5063 * 5598 *
5064 * See [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]. 5599 * See [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER].
5065 */ 5600 */
5066 bool _checkForStaticAccessToInstanceMember( 5601 void _checkForStaticAccessToInstanceMember(
5067 ClassElement typeReference, SimpleIdentifier name) { 5602 ClassElement typeReference, SimpleIdentifier name) {
5603 // OK, in comment
5604 if (_isInComment) {
5605 return;
5606 }
5068 // OK, target is not a type 5607 // OK, target is not a type
5069 if (typeReference == null) { 5608 if (typeReference == null) {
5070 return false; 5609 return;
5071 } 5610 }
5072 // prepare member Element 5611 // prepare member Element
5073 Element element = name.staticElement; 5612 Element element = name.staticElement;
5074 if (element is! ExecutableElement) { 5613 if (element is ExecutableElement) {
5075 return false; 5614 // OK, static
5615 if (element.isStatic) {
5616 return;
5617 }
5618 _errorReporter.reportErrorForNode(
5619 StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
5620 name,
5621 [name.name]);
5076 } 5622 }
5077 ExecutableElement memberElement = element as ExecutableElement;
5078 // OK, static
5079 if (memberElement.isStatic) {
5080 return false;
5081 }
5082 // report problem
5083 _errorReporter.reportErrorForNode(
5084 StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]);
5085 return true;
5086 } 5623 }
5087 5624
5088 /** 5625 /**
5089 * Check that the type of the expression in the given 'switch' [statement] is 5626 * Check that the type of the expression in the given 'switch' [statement] is
5090 * assignable to the type of the 'case' members. 5627 * assignable to the type of the 'case' members.
5091 * 5628 *
5092 * See [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE]. 5629 * See [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE].
5093 */ 5630 */
5094 bool _checkForSwitchExpressionNotAssignable(SwitchStatement statement) { 5631 void _checkForSwitchExpressionNotAssignable(SwitchStatement statement) {
5095 // prepare 'switch' expression type 5632 // prepare 'switch' expression type
5096 Expression expression = statement.expression; 5633 Expression expression = statement.expression;
5097 DartType expressionType = getStaticType(expression); 5634 DartType expressionType = getStaticType(expression);
5098 if (expressionType == null) { 5635 if (expressionType == null) {
5099 return false; 5636 return;
5100 } 5637 }
5101 // compare with type of the first 'case' 5638
5102 NodeList<SwitchMember> members = statement.members; 5639 // compare with type of the first non-default 'case'
5103 for (SwitchMember switchMember in members) { 5640 SwitchCase switchCase = statement.members
5104 if (switchMember is! SwitchCase) { 5641 .firstWhere((member) => member is SwitchCase, orElse: () => null);
5105 continue; 5642 if (switchCase == null) {
5106 } 5643 return;
5107 SwitchCase switchCase = switchMember as SwitchCase; 5644 }
5108 // prepare 'case' type 5645
5109 Expression caseExpression = switchCase.expression; 5646 Expression caseExpression = switchCase.expression;
5110 DartType caseType = getStaticType(caseExpression); 5647 DartType caseType = getStaticType(caseExpression);
5111 // check types 5648
5112 if (_typeSystem.isAssignableTo(expressionType, caseType)) { 5649 // check types
5113 return false; 5650 if (!_expressionIsAssignableAtType(expression, expressionType, caseType)) {
5114 }
5115 // report problem
5116 _errorReporter.reportErrorForNode( 5651 _errorReporter.reportErrorForNode(
5117 StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE, 5652 StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE,
5118 expression, 5653 expression,
5119 [expressionType, caseType]); 5654 [expressionType, caseType]);
5120 return true;
5121 } 5655 }
5122 return false;
5123 } 5656 }
5124 5657
5125 /** 5658 /**
5126 * Verify that the given function type [alias] does not reference itself 5659 * Verify that the given function type [alias] does not reference itself
5127 * directly. 5660 * directly.
5128 * 5661 *
5129 * See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]. 5662 * See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF].
5130 */ 5663 */
5131 bool _checkForTypeAliasCannotReferenceItself_function( 5664 void _checkForTypeAliasCannotReferenceItself_function(
5132 FunctionTypeAlias alias) { 5665 FunctionTypeAlias alias) {
5133 FunctionTypeAliasElement element = alias.element; 5666 if (_hasTypedefSelfReference(alias.element)) {
5134 if (!_hasTypedefSelfReference(element)) { 5667 _errorReporter.reportErrorForNode(
5135 return false; 5668 CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, alias);
5136 } 5669 }
5137 _errorReporter.reportErrorForNode(
5138 CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, alias);
5139 return true;
5140 } 5670 }
5141 5671
5142 /** 5672 /**
5143 * Verify that the given type [name] is not a deferred type. 5673 * Verify that the given type [name] is not a deferred type.
5144 * 5674 *
5145 * See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS]. 5675 * See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS].
5146 */ 5676 */
5147 bool _checkForTypeAnnotationDeferredClass(TypeName name) { 5677 void _checkForTypeAnnotationDeferredClass(TypeName name) {
5148 if (name != null && name.isDeferred) { 5678 if (name != null && name.isDeferred) {
5149 _errorReporter.reportErrorForNode( 5679 _errorReporter.reportErrorForNode(
5150 StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, name, [name.name]); 5680 StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, name, [name.name]);
5151 } 5681 }
5152 return false;
5153 } 5682 }
5154 5683
5155 /** 5684 /**
5156 * Verify that the type arguments in the given [typeName] are all within 5685 * Verify that the type arguments in the given [typeName] are all within
5157 * their bounds. 5686 * their bounds.
5158 * 5687 *
5159 * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]. 5688 * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
5160 */ 5689 */
5161 bool _checkForTypeArgumentNotMatchingBounds(TypeName typeName) { 5690 void _checkForTypeArgumentNotMatchingBounds(TypeName typeName) {
5162 if (typeName.typeArguments == null) { 5691 if (typeName.typeArguments == null) {
5163 return false; 5692 return;
5164 } 5693 }
5165 // prepare Type 5694 // prepare Type
5166 DartType type = typeName.type; 5695 DartType type = typeName.type;
5167 if (type == null) { 5696 if (type == null) {
5168 return false; 5697 return;
5169 } 5698 }
5170 // prepare ClassElement
5171 Element element = type.element; 5699 Element element = type.element;
5172 if (element is! ClassElement) { 5700 if (element is ClassElement) {
5173 return false; 5701 // prepare type parameters
5174 } 5702 List<TypeParameterElement> parameterElements = element.typeParameters;
5175 ClassElement classElement = element as ClassElement; 5703 List<DartType> parameterTypes = element.type.typeArguments;
5176 // prepare type parameters 5704 List<DartType> arguments = (type as ParameterizedType).typeArguments;
5177 List<DartType> typeParameters = classElement.type.typeArguments; 5705 // iterate over each bounded type parameter and corresponding argument
5178 List<TypeParameterElement> boundingElts = classElement.typeParameters; 5706 NodeList<TypeName> typeNameArgList = typeName.typeArguments.arguments;
5179 // iterate over each bounded type parameter and corresponding argument 5707 int loopThroughIndex =
5180 NodeList<TypeName> typeNameArgList = typeName.typeArguments.arguments; 5708 math.min(typeNameArgList.length, parameterElements.length);
5181 List<DartType> typeArguments = (type as InterfaceType).typeArguments; 5709 bool shouldSubstitute =
5182 int loopThroughIndex = 5710 arguments.length != 0 && arguments.length == parameterTypes.length;
5183 math.min(typeNameArgList.length, boundingElts.length); 5711 for (int i = 0; i < loopThroughIndex; i++) {
5184 bool foundError = false; 5712 TypeName argTypeName = typeNameArgList[i];
5185 for (int i = 0; i < loopThroughIndex; i++) { 5713 DartType argType = argTypeName.type;
5186 TypeName argTypeName = typeNameArgList[i]; 5714 DartType boundType = parameterElements[i].bound;
5187 DartType argType = argTypeName.type; 5715 if (argType != null && boundType != null) {
5188 DartType boundType = boundingElts[i].bound; 5716 if (shouldSubstitute) {
5189 if (argType != null && boundType != null) { 5717 boundType = boundType.substitute2(arguments, parameterTypes);
5190 if (typeArguments.length != 0 &&
5191 typeArguments.length == typeParameters.length) {
5192 boundType = boundType.substitute2(typeArguments, typeParameters);
5193 }
5194 if (!_typeSystem.isSubtypeOf(argType, boundType)) {
5195 ErrorCode errorCode;
5196 if (_isInConstInstanceCreation) {
5197 errorCode = CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
5198 } else {
5199 errorCode = StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
5200 } 5718 }
5201 _errorReporter.reportTypeErrorForNode( 5719 if (!_typeSystem.isSubtypeOf(argType, boundType)) {
5202 errorCode, argTypeName, [argType, boundType]); 5720 ErrorCode errorCode;
5203 foundError = true; 5721 if (_isInConstInstanceCreation) {
5722 errorCode =
5723 CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
5724 } else {
5725 errorCode =
5726 StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
5727 }
5728 _errorReporter.reportTypeErrorForNode(
5729 errorCode, argTypeName, [argType, boundType]);
5730 }
5204 } 5731 }
5205 } 5732 }
5206 } 5733 }
5207 return foundError;
5208 } 5734 }
5209 5735
5210 /** 5736 /**
5211 * Check whether the given type [name] is a type parameter being used to 5737 * Check whether the given type [name] is a type parameter being used to
5212 * define a static member. 5738 * define a static member.
5213 * 5739 *
5214 * See [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]. 5740 * See [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC].
5215 */ 5741 */
5216 bool _checkForTypeParameterReferencedByStatic(TypeName name) { 5742 void _checkForTypeParameterReferencedByStatic(TypeName name) {
5217 if (_isInStaticMethod || _isInStaticVariableDeclaration) { 5743 if (_isInStaticMethod || _isInStaticVariableDeclaration) {
5218 DartType type = name.type; 5744 DartType type = name.type;
5219 if (type is TypeParameterType) { 5745 // The class's type parameters are not in scope for static methods.
5746 // However all other type parameters are legal (e.g. the static method's
5747 // type parameters, or a local function's type parameters).
5748 if (type is TypeParameterType &&
5749 type.element.enclosingElement is ClassElement) {
5220 _errorReporter.reportErrorForNode( 5750 _errorReporter.reportErrorForNode(
5221 StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, name); 5751 StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, name);
5222 return true;
5223 } 5752 }
5224 } 5753 }
5225 return false;
5226 } 5754 }
5227 5755
5228 /** 5756 /**
5229 * Check whether the given type [parameter] is a supertype of its bound. 5757 * Check whether the given type [parameter] is a supertype of its bound.
5230 * 5758 *
5231 * See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND]. 5759 * See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND].
5232 */ 5760 */
5233 bool _checkForTypeParameterSupertypeOfItsBound(TypeParameter parameter) { 5761 void _checkForTypeParameterSupertypeOfItsBound(TypeParameter parameter) {
5234 TypeParameterElement element = parameter.element; 5762 TypeParameterElement element = parameter.element;
5235 // prepare bound 5763 // prepare bound
5236 DartType bound = element.bound; 5764 DartType bound = element.bound;
5237 if (bound == null) { 5765 if (bound == null) {
5238 return false; 5766 return;
5239 } 5767 }
5240 // OK, type parameter is not supertype of its bound 5768 // OK, type parameter is not supertype of its bound
5241 if (!bound.isMoreSpecificThan(element.type)) { 5769 if (!bound.isMoreSpecificThan(element.type)) {
5242 return false; 5770 return;
5243 } 5771 }
5244 // report problem 5772
5245 _errorReporter.reportErrorForNode( 5773 _errorReporter.reportErrorForNode(
5246 StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, 5774 StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND,
5247 parameter, 5775 parameter,
5248 [element.displayName]); 5776 [element.displayName]);
5249 return true;
5250 } 5777 }
5251 5778
5252 /** 5779 /**
5253 * Check that if the given generative [constructor] has neither an explicit 5780 * Check that if the given generative [constructor] has neither an explicit
5254 * super constructor invocation nor a redirecting constructor invocation, that 5781 * super constructor invocation nor a redirecting constructor invocation, that
5255 * the superclass has a default generative constructor. 5782 * the superclass has a default generative constructor.
5256 * 5783 *
5257 * See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT], 5784 * See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT],
5258 * [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and 5785 * [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and
5259 * [StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]. 5786 * [StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT].
5260 */ 5787 */
5261 bool _checkForUndefinedConstructorInInitializerImplicit( 5788 void _checkForUndefinedConstructorInInitializerImplicit(
5262 ConstructorDeclaration constructor) { 5789 ConstructorDeclaration constructor) {
5263 if (_enclosingClass == null) { 5790 if (_enclosingClass == null) {
5264 return false; 5791 return;
5265 } 5792 }
5266 // do nothing if mixin errors have already been reported for this class. 5793 // do nothing if mixin errors have already been reported for this class.
5267 ClassElementImpl enclosingClass = _enclosingClass; 5794 if (_enclosingClass.doesMixinLackConstructors) {
5268 if (enclosingClass.doesMixinLackConstructors) { 5795 return;
5269 return false;
5270 } 5796 }
5271 // 5797
5272 // Ignore if the constructor is not generative. 5798 // Ignore if the constructor is not generative.
5273 //
5274 if (constructor.factoryKeyword != null) { 5799 if (constructor.factoryKeyword != null) {
5275 return false; 5800 return;
5276 } 5801 }
5277 // 5802
5278 // Ignore if the constructor has either an implicit super constructor 5803 // Ignore if the constructor has either an implicit super constructor
5279 // invocation or a redirecting constructor invocation. 5804 // invocation or a redirecting constructor invocation.
5280 //
5281 for (ConstructorInitializer constructorInitializer 5805 for (ConstructorInitializer constructorInitializer
5282 in constructor.initializers) { 5806 in constructor.initializers) {
5283 if (constructorInitializer is SuperConstructorInvocation || 5807 if (constructorInitializer is SuperConstructorInvocation ||
5284 constructorInitializer is RedirectingConstructorInvocation) { 5808 constructorInitializer is RedirectingConstructorInvocation) {
5285 return false; 5809 return;
5286 } 5810 }
5287 } 5811 }
5288 // 5812
5289 // Check to see whether the superclass has a non-factory unnamed 5813 // Check to see whether the superclass has a non-factory unnamed
5290 // constructor. 5814 // constructor.
5291 //
5292 InterfaceType superType = _enclosingClass.supertype; 5815 InterfaceType superType = _enclosingClass.supertype;
5293 if (superType == null) { 5816 if (superType == null) {
5294 return false; 5817 return;
5295 } 5818 }
5296 ClassElement superElement = superType.element; 5819 ClassElement superElement = superType.element;
5297 ConstructorElement superUnnamedConstructor = 5820 ConstructorElement superUnnamedConstructor =
5298 superElement.unnamedConstructor; 5821 superElement.unnamedConstructor;
5299 if (superUnnamedConstructor != null) { 5822 if (superUnnamedConstructor != null) {
5300 if (superUnnamedConstructor.isFactory) { 5823 if (superUnnamedConstructor.isFactory) {
5301 _errorReporter.reportErrorForNode( 5824 _errorReporter.reportErrorForNode(
5302 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, 5825 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
5303 constructor.returnType, 5826 constructor.returnType,
5304 [superUnnamedConstructor]); 5827 [superUnnamedConstructor]);
5305 return true; 5828 } else if (!superUnnamedConstructor.isDefaultConstructor ||
5306 }
5307 if (!superUnnamedConstructor.isDefaultConstructor ||
5308 !_enclosingClass 5829 !_enclosingClass
5309 .isSuperConstructorAccessible(superUnnamedConstructor)) { 5830 .isSuperConstructorAccessible(superUnnamedConstructor)) {
5310 int offset; 5831 Identifier returnType = constructor.returnType;
5311 int length; 5832 SimpleIdentifier name = constructor.name;
5312 { 5833 int offset = returnType.offset;
5313 Identifier returnType = constructor.returnType; 5834 int length = (name != null ? name.end : returnType.end) - offset;
5314 SimpleIdentifier name = constructor.name;
5315 offset = returnType.offset;
5316 length = (name != null ? name.end : returnType.end) - offset;
5317 }
5318 _errorReporter.reportErrorForOffset( 5835 _errorReporter.reportErrorForOffset(
5319 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, 5836 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT,
5320 offset, 5837 offset,
5321 length, 5838 length,
5322 [superType.displayName]); 5839 [superType.displayName]);
5323 } 5840 }
5324 return false; 5841 } else {
5842 _errorReporter.reportErrorForNode(
5843 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
5844 constructor.returnType,
5845 [superElement.name]);
5325 } 5846 }
5326 _errorReporter.reportErrorForNode(
5327 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
5328 constructor.returnType,
5329 [superElement.name]);
5330 return true;
5331 } 5847 }
5332 5848
5333 /** 5849 /**
5334 * Check that if the given [name] is a reference to a static member it is 5850 * Check that if the given [name] is a reference to a static member it is
5335 * defined in the enclosing class rather than in a superclass. 5851 * defined in the enclosing class rather than in a superclass.
5336 * 5852 *
5337 * See [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER ]. 5853 * See [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER ].
5338 */ 5854 */
5339 bool _checkForUnqualifiedReferenceToNonLocalStaticMember( 5855 void _checkForUnqualifiedReferenceToNonLocalStaticMember(
5340 SimpleIdentifier name) { 5856 SimpleIdentifier name) {
5341 Element element = name.staticElement; 5857 Element element = name.staticElement;
5342 if (element == null || element is TypeParameterElement) { 5858 if (element == null || element is TypeParameterElement) {
5343 return false; 5859 return;
5344 } 5860 }
5345 Element enclosingElement = element.enclosingElement; 5861 Element enclosingElement = element.enclosingElement;
5862 if (identical(enclosingElement, _enclosingClass)) {
5863 return;
5864 }
5865 if (identical(enclosingElement, _enclosingEnum)) {
5866 return;
5867 }
5346 if (enclosingElement is! ClassElement) { 5868 if (enclosingElement is! ClassElement) {
5347 return false; 5869 return;
5348 } 5870 }
5349 if ((element is MethodElement && !element.isStatic) || 5871 if ((element is MethodElement && !element.isStatic) ||
5350 (element is PropertyAccessorElement && !element.isStatic)) { 5872 (element is PropertyAccessorElement && !element.isStatic)) {
5351 return false; 5873 return;
5352 }
5353 if (identical(enclosingElement, _enclosingClass)) {
5354 return false;
5355 } 5874 }
5356 _errorReporter.reportErrorForNode( 5875 _errorReporter.reportErrorForNode(
5357 StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, 5876 StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
5358 name, 5877 name,
5359 [name.name]); 5878 [name.name]);
5360 return true;
5361 } 5879 }
5362 5880
5363 void _checkForValidField(FieldFormalParameter parameter) { 5881 void _checkForValidField(FieldFormalParameter parameter) {
5364 ParameterElement element = parameter.element; 5882 ParameterElement element = parameter.element;
5365 if (element is FieldFormalParameterElement) { 5883 if (element is FieldFormalParameterElement) {
5366 FieldElement fieldElement = element.field; 5884 FieldElement fieldElement = element.field;
5367 if (fieldElement == null || fieldElement.isSynthetic) { 5885 if (fieldElement == null || fieldElement.isSynthetic) {
5368 _errorReporter.reportErrorForNode( 5886 _errorReporter.reportErrorForNode(
5369 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, 5887 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
5370 parameter, 5888 parameter,
5371 [parameter.identifier.name]); 5889 [parameter.identifier.name]);
5372 } else { 5890 } else {
5373 ParameterElement parameterElement = parameter.element; 5891 ParameterElement parameterElement = parameter.element;
5374 if (parameterElement is FieldFormalParameterElementImpl) { 5892 if (parameterElement is FieldFormalParameterElementImpl) {
5375 FieldFormalParameterElementImpl fieldFormal = parameterElement; 5893 DartType declaredType = parameterElement.type;
5376 DartType declaredType = fieldFormal.type;
5377 DartType fieldType = fieldElement.type; 5894 DartType fieldType = fieldElement.type;
5378 if (fieldElement.isSynthetic) { 5895 if (fieldElement.isSynthetic) {
5379 _errorReporter.reportErrorForNode( 5896 _errorReporter.reportErrorForNode(
5380 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, 5897 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
5381 parameter, 5898 parameter,
5382 [parameter.identifier.name]); 5899 [parameter.identifier.name]);
5383 } else if (fieldElement.isStatic) { 5900 } else if (fieldElement.isStatic) {
5384 _errorReporter.reportErrorForNode( 5901 _errorReporter.reportErrorForNode(
5385 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, 5902 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD,
5386 parameter, 5903 parameter,
(...skipping 25 matching lines...) Expand all
5412 // // TODO(jwren) Report error, constructor initializer variable is a top level element 5929 // // TODO(jwren) Report error, constructor initializer variable is a top level element
5413 // // (Either here or in ErrorVerifier.checkForAllFinalInitializedErrorCo des) 5930 // // (Either here or in ErrorVerifier.checkForAllFinalInitializedErrorCo des)
5414 // } 5931 // }
5415 } 5932 }
5416 5933
5417 /** 5934 /**
5418 * Verify that the given [getter] does not have a return type of 'void'. 5935 * Verify that the given [getter] does not have a return type of 'void'.
5419 * 5936 *
5420 * See [StaticWarningCode.VOID_RETURN_FOR_GETTER]. 5937 * See [StaticWarningCode.VOID_RETURN_FOR_GETTER].
5421 */ 5938 */
5422 bool _checkForVoidReturnType(MethodDeclaration getter) { 5939 void _checkForVoidReturnType(MethodDeclaration getter) {
5423 TypeName returnType = getter.returnType; 5940 TypeName returnType = getter.returnType;
5424 if (returnType == null || returnType.name.name != "void") { 5941 if (returnType == null || returnType.name.name != "void") {
5425 return false; 5942 return;
5426 } 5943 }
5427 _errorReporter.reportErrorForNode( 5944 _errorReporter.reportErrorForNode(
5428 StaticWarningCode.VOID_RETURN_FOR_GETTER, returnType); 5945 StaticWarningCode.VOID_RETURN_FOR_GETTER, returnType);
5429 return true;
5430 } 5946 }
5431 5947
5432 /** 5948 /**
5433 * Verify the given operator-method [declaration], has correct number of 5949 * Verify the given operator-method [declaration], has correct number of
5434 * parameters. 5950 * parameters.
5435 * 5951 *
5436 * This method assumes that the method declaration was tested to be an 5952 * This method assumes that the method declaration was tested to be an
5437 * operator declaration before being called. 5953 * operator declaration before being called.
5438 * 5954 *
5439 * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR]. 5955 * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR].
5440 */ 5956 */
5441 bool _checkForWrongNumberOfParametersForOperator( 5957 void _checkForWrongNumberOfParametersForOperator(
5442 MethodDeclaration declaration) { 5958 MethodDeclaration declaration) {
5443 // prepare number of parameters 5959 // prepare number of parameters
5444 FormalParameterList parameterList = declaration.parameters; 5960 FormalParameterList parameterList = declaration.parameters;
5445 if (parameterList == null) { 5961 if (parameterList == null) {
5446 return false; 5962 return;
5447 } 5963 }
5448 int numParameters = parameterList.parameters.length; 5964 int numParameters = parameterList.parameters.length;
5449 // prepare operator name 5965 // prepare operator name
5450 SimpleIdentifier nameNode = declaration.name; 5966 SimpleIdentifier nameNode = declaration.name;
5451 if (nameNode == null) { 5967 if (nameNode == null) {
5452 return false; 5968 return;
5453 } 5969 }
5454 String name = nameNode.name; 5970 String name = nameNode.name;
5455 // check for exact number of parameters 5971 // check for exact number of parameters
5456 int expected = -1; 5972 int expected = -1;
5457 if ("[]=" == name) { 5973 if ("[]=" == name) {
5458 expected = 2; 5974 expected = 2;
5459 } else if ("<" == name || 5975 } else if ("<" == name ||
5460 ">" == name || 5976 ">" == name ||
5461 "<=" == name || 5977 "<=" == name ||
5462 ">=" == name || 5978 ">=" == name ||
(...skipping 11 matching lines...) Expand all
5474 "[]" == name) { 5990 "[]" == name) {
5475 expected = 1; 5991 expected = 1;
5476 } else if ("~" == name) { 5992 } else if ("~" == name) {
5477 expected = 0; 5993 expected = 0;
5478 } 5994 }
5479 if (expected != -1 && numParameters != expected) { 5995 if (expected != -1 && numParameters != expected) {
5480 _errorReporter.reportErrorForNode( 5996 _errorReporter.reportErrorForNode(
5481 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR, 5997 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR,
5482 nameNode, 5998 nameNode,
5483 [name, expected, numParameters]); 5999 [name, expected, numParameters]);
5484 return true; 6000 } else if ("-" == name && numParameters > 1) {
5485 }
5486 // check for operator "-"
5487 if ("-" == name && numParameters > 1) {
5488 _errorReporter.reportErrorForNode( 6001 _errorReporter.reportErrorForNode(
5489 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS, 6002 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS,
5490 nameNode, 6003 nameNode,
5491 [numParameters]); 6004 [numParameters]);
5492 return true;
5493 } 6005 }
5494 // OK
5495 return false;
5496 } 6006 }
5497 6007
5498 /** 6008 /**
5499 * Verify that the given setter [parameterList] has only one required 6009 * Verify that the given setter [parameterList] has only one required
5500 * parameter. The [setterName] is the name of the setter to report problems 6010 * parameter. The [setterName] is the name of the setter to report problems
5501 * on. 6011 * on.
5502 * 6012 *
5503 * This method assumes that the method declaration was tested to be a setter 6013 * This method assumes that the method declaration was tested to be a setter
5504 * before being called. 6014 * before being called.
5505 * 6015 *
5506 * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]. 6016 * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER].
5507 */ 6017 */
5508 bool _checkForWrongNumberOfParametersForSetter( 6018 void _checkForWrongNumberOfParametersForSetter(
5509 SimpleIdentifier setterName, FormalParameterList parameterList) { 6019 SimpleIdentifier setterName, FormalParameterList parameterList) {
5510 if (setterName == null) { 6020 if (setterName == null || parameterList == null) {
5511 return false; 6021 return;
5512 } 6022 }
5513 if (parameterList == null) { 6023
5514 return false;
5515 }
5516 NodeList<FormalParameter> parameters = parameterList.parameters; 6024 NodeList<FormalParameter> parameters = parameterList.parameters;
5517 if (parameters.length != 1 || 6025 if (parameters.length != 1 ||
5518 parameters[0].kind != ParameterKind.REQUIRED) { 6026 parameters[0].kind != ParameterKind.REQUIRED) {
5519 _errorReporter.reportErrorForNode( 6027 _errorReporter.reportErrorForNode(
5520 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, 6028 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
5521 setterName); 6029 setterName);
5522 return true;
5523 } 6030 }
5524 return false;
5525 } 6031 }
5526 6032
5527 /** 6033 /**
5528 * Check for a type mis-match between the yielded type and the declared 6034 * Check for a type mis-match between the yielded type and the declared
5529 * return type of a generator function. 6035 * return type of a generator function.
5530 * 6036 *
5531 * This method should only be called in generator functions. 6037 * This method should only be called in generator functions.
5532 */ 6038 */
5533 bool _checkForYieldOfInvalidType( 6039 void _checkForYieldOfInvalidType(
5534 Expression yieldExpression, bool isYieldEach) { 6040 Expression yieldExpression, bool isYieldEach) {
5535 assert(_inGenerator); 6041 assert(_inGenerator);
5536 if (_enclosingFunction == null) { 6042 if (_enclosingFunction == null) {
5537 return false; 6043 return;
5538 } 6044 }
5539 DartType declaredReturnType = _enclosingFunction.returnType; 6045 DartType declaredReturnType = _enclosingFunction.returnType;
5540 DartType staticYieldedType = getStaticType(yieldExpression); 6046 DartType staticYieldedType = getStaticType(yieldExpression);
5541 DartType impliedReturnType; 6047 DartType impliedReturnType;
5542 if (isYieldEach) { 6048 if (isYieldEach) {
5543 impliedReturnType = staticYieldedType; 6049 impliedReturnType = staticYieldedType;
5544 } else if (_enclosingFunction.isAsynchronous) { 6050 } else if (_enclosingFunction.isAsynchronous) {
5545 impliedReturnType = 6051 impliedReturnType =
5546 _typeProvider.streamType.substitute4(<DartType>[staticYieldedType]); 6052 _typeProvider.streamType.instantiate(<DartType>[staticYieldedType]);
5547 } else { 6053 } else {
5548 impliedReturnType = 6054 impliedReturnType =
5549 _typeProvider.iterableType.substitute4(<DartType>[staticYieldedType]); 6055 _typeProvider.iterableType.instantiate(<DartType>[staticYieldedType]);
5550 } 6056 }
5551 if (!_typeSystem.isAssignableTo(impliedReturnType, declaredReturnType)) { 6057 if (!_checkForAssignableExpressionAtType(yieldExpression, impliedReturnType,
5552 _errorReporter.reportTypeErrorForNode( 6058 declaredReturnType, StaticTypeWarningCode.YIELD_OF_INVALID_TYPE)) {
5553 StaticTypeWarningCode.YIELD_OF_INVALID_TYPE, 6059 return;
5554 yieldExpression,
5555 [impliedReturnType, declaredReturnType]);
5556 return true;
5557 } 6060 }
5558 if (isYieldEach) { 6061 if (isYieldEach) {
5559 // Since the declared return type might have been "dynamic", we need to 6062 // Since the declared return type might have been "dynamic", we need to
5560 // also check that the implied return type is assignable to generic 6063 // also check that the implied return type is assignable to generic
5561 // Stream/Iterable. 6064 // Stream/Iterable.
5562 DartType requiredReturnType; 6065 DartType requiredReturnType;
5563 if (_enclosingFunction.isAsynchronous) { 6066 if (_enclosingFunction.isAsynchronous) {
5564 requiredReturnType = _typeProvider.streamDynamicType; 6067 requiredReturnType = _typeProvider.streamDynamicType;
5565 } else { 6068 } else {
5566 requiredReturnType = _typeProvider.iterableDynamicType; 6069 requiredReturnType = _typeProvider.iterableDynamicType;
5567 } 6070 }
5568 if (!_typeSystem.isAssignableTo(impliedReturnType, requiredReturnType)) { 6071 if (!_typeSystem.isAssignableTo(impliedReturnType, requiredReturnType)) {
5569 _errorReporter.reportTypeErrorForNode( 6072 _errorReporter.reportTypeErrorForNode(
5570 StaticTypeWarningCode.YIELD_OF_INVALID_TYPE, 6073 StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
5571 yieldExpression, 6074 yieldExpression,
5572 [impliedReturnType, requiredReturnType]); 6075 [impliedReturnType, requiredReturnType]);
5573 return true; 6076 return;
5574 } 6077 }
5575 } 6078 }
5576 return false;
5577 } 6079 }
5578 6080
5579 /** 6081 /**
5580 * Verify that if the given class [declaration] implements the class Function 6082 * Verify that if the given class [declaration] implements the class Function
5581 * that it has a concrete implementation of the call method. 6083 * that it has a concrete implementation of the call method.
5582 * 6084 *
5583 * See [StaticWarningCode.FUNCTION_WITHOUT_CALL]. 6085 * See [StaticWarningCode.FUNCTION_WITHOUT_CALL].
5584 */ 6086 */
5585 bool _checkImplementsFunctionWithoutCall(ClassDeclaration declaration) { 6087 void _checkImplementsFunctionWithoutCall(ClassDeclaration declaration) {
5586 if (declaration.isAbstract) { 6088 if (declaration.isAbstract) {
5587 return false; 6089 return;
5588 } 6090 }
5589 ClassElement classElement = declaration.element; 6091 ClassElement classElement = declaration.element;
5590 if (classElement == null) { 6092 if (classElement == null) {
5591 return false; 6093 return;
5592 } 6094 }
5593 if (!_typeSystem.isSubtypeOf( 6095 if (!_typeSystem.isSubtypeOf(
5594 classElement.type, _typeProvider.functionType)) { 6096 classElement.type, _typeProvider.functionType)) {
5595 return false; 6097 return;
5596 } 6098 }
5597 // If there is a noSuchMethod method, then don't report the warning, 6099 // If there is a noSuchMethod method, then don't report the warning,
5598 // see dartbug.com/16078 6100 // see dartbug.com/16078
5599 if (classElement.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME) != 6101 if (_enclosingClass.hasNoSuchMethod) {
5600 null) { 6102 return;
5601 return false;
5602 } 6103 }
5603 ExecutableElement callMethod = _inheritanceManager.lookupMember( 6104 ExecutableElement callMethod = _inheritanceManager.lookupMember(
5604 classElement, FunctionElement.CALL_METHOD_NAME); 6105 classElement, FunctionElement.CALL_METHOD_NAME);
5605 if (callMethod == null || 6106 if (callMethod == null ||
5606 callMethod is! MethodElement || 6107 callMethod is! MethodElement ||
5607 (callMethod as MethodElement).isAbstract) { 6108 (callMethod as MethodElement).isAbstract) {
5608 _errorReporter.reportErrorForNode( 6109 _errorReporter.reportErrorForNode(
5609 StaticWarningCode.FUNCTION_WITHOUT_CALL, declaration.name); 6110 StaticWarningCode.FUNCTION_WITHOUT_CALL, declaration.name);
5610 return true;
5611 } 6111 }
5612 return false;
5613 } 6112 }
5614 6113
5615 /** 6114 /**
5616 * Verify that the given class [declaration] does not have the same class in 6115 * Verify that the given class [declaration] does not have the same class in
5617 * the 'extends' and 'implements' clauses. 6116 * the 'extends' and 'implements' clauses.
5618 * 6117 *
5619 * See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]. 6118 * See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS].
5620 */ 6119 */
5621 bool _checkImplementsSuperClass(ClassDeclaration declaration) { 6120 void _checkImplementsSuperClass(ClassDeclaration declaration) {
5622 // prepare super type 6121 // prepare super type
5623 InterfaceType superType = _enclosingClass.supertype; 6122 InterfaceType superType = _enclosingClass.supertype;
5624 if (superType == null) { 6123 if (superType == null) {
5625 return false; 6124 return;
5626 } 6125 }
5627 // prepare interfaces 6126 // prepare interfaces
5628 ImplementsClause implementsClause = declaration.implementsClause; 6127 ImplementsClause implementsClause = declaration.implementsClause;
5629 if (implementsClause == null) { 6128 if (implementsClause == null) {
5630 return false; 6129 return;
5631 } 6130 }
5632 // check interfaces 6131 // check interfaces
5633 bool hasProblem = false;
5634 for (TypeName interfaceNode in implementsClause.interfaces) { 6132 for (TypeName interfaceNode in implementsClause.interfaces) {
5635 if (interfaceNode.type == superType) { 6133 if (interfaceNode.type == superType) {
5636 hasProblem = true;
5637 _errorReporter.reportErrorForNode( 6134 _errorReporter.reportErrorForNode(
5638 CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, 6135 CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
5639 interfaceNode, 6136 interfaceNode,
5640 [superType.displayName]); 6137 [superType.displayName]);
5641 } 6138 }
5642 } 6139 }
5643 // done 6140 }
5644 return hasProblem; 6141
6142 /**
6143 * Verify that the given [typeArguments] are all within their bounds, as
6144 * defined by the given [element].
6145 *
6146 * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
6147 */
6148 void _checkTypeArguments(Element element, TypeArgumentList typeArguments,
6149 [DartType targetType]) {
6150 if (element == null || typeArguments == null) {
6151 return;
6152 }
6153 void reportError(
6154 TypeName argument, DartType argumentType, DartType parameterType) {
6155 _errorReporter.reportTypeErrorForNode(
6156 StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
6157 argument,
6158 [argumentType, parameterType]);
6159 }
6160
6161 if (element is FunctionTypedElement) {
6162 _checkTypeArgumentsAgainstBounds(
6163 element.typeParameters, typeArguments, targetType, reportError);
6164 } else if (element is ClassElement) {
6165 _checkTypeArgumentsAgainstBounds(
6166 element.typeParameters, typeArguments, targetType, reportError);
6167 } else if (element is ParameterElement || element is LocalVariableElement) {
6168 // TODO(brianwilkerson) Implement this case
6169 } else {
6170 print('Unhandled element type: ${element.runtimeType}');
6171 }
6172 }
6173
6174 void _checkTypeArgumentsAgainstBounds(
6175 List<TypeParameterElement> typeParameters,
6176 TypeArgumentList typeArgumentList,
6177 DartType targetType,
6178 void reportError(
6179 TypeName argument, DartType argumentType, DartType parameterType)) {
6180 NodeList<TypeName> typeArguments = typeArgumentList.arguments;
6181 int argumentsLength = typeArguments.length;
6182 int maxIndex = math.min(typeParameters.length, argumentsLength);
6183
6184 bool shouldSubstitute =
6185 argumentsLength != 0 && argumentsLength == typeParameters.length;
6186 List<DartType> argumentTypes = shouldSubstitute
6187 ? typeArguments.map((TypeName typeName) => typeName.type).toList()
6188 : null;
6189 List<DartType> parameterTypes = shouldSubstitute
6190 ? typeParameters
6191 .map((TypeParameterElement element) => element.type)
6192 .toList()
6193 : null;
6194 List<DartType> targetTypeParameterTypes = null;
6195 for (int i = 0; i < maxIndex; i++) {
6196 TypeName argTypeName = typeArguments[i];
6197 DartType argType = argTypeName.type;
6198 DartType boundType = typeParameters[i].bound;
6199 if (argType != null && boundType != null) {
6200 if (targetType is ParameterizedType) {
6201 if (targetTypeParameterTypes == null) {
6202 targetTypeParameterTypes = targetType.typeParameters
6203 .map((TypeParameterElement element) => element.type)
6204 .toList();
6205 }
6206 boundType = boundType.substitute2(
6207 targetType.typeArguments, targetTypeParameterTypes);
6208 }
6209 if (shouldSubstitute) {
6210 boundType = boundType.substitute2(argumentTypes, parameterTypes);
6211 }
6212 if (!_typeSystem.isSubtypeOf(argType, boundType)) {
6213 reportError(argTypeName, argType, boundType);
6214 }
6215 }
6216 }
5645 } 6217 }
5646 6218
5647 DartType _computeReturnTypeForMethod(Expression returnExpression) { 6219 DartType _computeReturnTypeForMethod(Expression returnExpression) {
5648 // This method should never be called for generators, since generators are 6220 // This method should never be called for generators, since generators are
5649 // never allowed to contain return statements with expressions. 6221 // never allowed to contain return statements with expressions.
5650 assert(!_inGenerator); 6222 assert(!_inGenerator);
5651 if (returnExpression == null) { 6223 if (returnExpression == null) {
5652 if (_enclosingFunction.isAsynchronous) { 6224 if (_enclosingFunction.isAsynchronous) {
5653 return _typeProvider.futureNullType; 6225 return _typeProvider.futureNullType;
5654 } else { 6226 } else {
5655 return VoidTypeImpl.instance; 6227 return VoidTypeImpl.instance;
5656 } 6228 }
5657 } 6229 }
5658 DartType staticReturnType = getStaticType(returnExpression); 6230 DartType staticReturnType = getStaticType(returnExpression);
5659 if (staticReturnType != null && _enclosingFunction.isAsynchronous) { 6231 if (staticReturnType != null && _enclosingFunction.isAsynchronous) {
5660 return _typeProvider.futureType.substitute4(<DartType>[ 6232 return _typeProvider.futureType.instantiate(
5661 StaticTypeAnalyzer.flattenFutures(_typeProvider, staticReturnType) 6233 <DartType>[staticReturnType.flattenFutures(_typeSystem)]);
5662 ]);
5663 } 6234 }
5664 return staticReturnType; 6235 return staticReturnType;
5665 } 6236 }
5666 6237
6238 bool _expressionIsAssignableAtType(Expression expression,
6239 DartType actualStaticType, DartType expectedStaticType) {
6240 bool concrete = _options.strongMode && checker.isKnownFunction(expression);
6241 if (concrete && actualStaticType is FunctionType) {
6242 actualStaticType = _typeSystem.functionTypeToConcreteType(
6243 _typeProvider, actualStaticType);
6244 // TODO(leafp): Move the Downcast functionality here.
6245 }
6246 return _typeSystem.isAssignableTo(actualStaticType, expectedStaticType);
6247 }
6248
6249 MethodElement _findOverriddenMemberThatMustCallSuper(MethodDeclaration node) {
6250 ExecutableElement overriddenMember = _getOverriddenMember(node.element);
6251 List<ExecutableElement> seen = <ExecutableElement>[];
6252 while (
6253 overriddenMember is MethodElement && !seen.contains(overriddenMember)) {
6254 for (ElementAnnotation annotation in overriddenMember.metadata) {
6255 if (annotation.isMustCallSuper) {
6256 return overriddenMember;
6257 }
6258 }
6259 seen.add(overriddenMember);
6260 // Keep looking up the chain.
6261 overriddenMember = _getOverriddenMember(overriddenMember);
6262 }
6263 return null;
6264 }
6265
5667 /** 6266 /**
5668 * Return the error code that should be used when the given class [element] 6267 * Return the error code that should be used when the given class [element]
5669 * references itself directly. 6268 * references itself directly.
5670 */ 6269 */
5671 ErrorCode _getBaseCaseErrorCode(ClassElement element) { 6270 ErrorCode _getBaseCaseErrorCode(ClassElement element) {
5672 InterfaceType supertype = element.supertype; 6271 InterfaceType supertype = element.supertype;
5673 if (supertype != null && _enclosingClass == supertype.element) { 6272 if (supertype != null && _enclosingClass == supertype.element) {
5674 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTE NDS; 6273 return CompileTimeErrorCode
6274 .RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS;
5675 } 6275 }
5676 List<InterfaceType> mixins = element.mixins; 6276 List<InterfaceType> mixins = element.mixins;
5677 for (int i = 0; i < mixins.length; i++) { 6277 for (int i = 0; i < mixins.length; i++) {
5678 if (_enclosingClass == mixins[i].element) { 6278 if (_enclosingClass == mixins[i].element) {
5679 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WI TH; 6279 return CompileTimeErrorCode
6280 .RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH;
5680 } 6281 }
5681 } 6282 }
5682 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEM ENTS; 6283 return CompileTimeErrorCode
6284 .RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS;
5683 } 6285 }
5684 6286
5685 /** 6287 /**
5686 * Given an [expression] in a switch case whose value is expected to be an 6288 * Given an [expression] in a switch case whose value is expected to be an
5687 * enum constant, return the name of the constant. 6289 * enum constant, return the name of the constant.
5688 */ 6290 */
5689 String _getConstantName(Expression expression) { 6291 String _getConstantName(Expression expression) {
5690 // TODO(brianwilkerson) Convert this to return the element representing the 6292 // TODO(brianwilkerson) Convert this to return the element representing the
5691 // constant. 6293 // constant.
5692 if (expression is SimpleIdentifier) { 6294 if (expression is SimpleIdentifier) {
(...skipping 12 matching lines...) Expand all
5705 DartType _getGetterType(PropertyAccessorElement getter) { 6307 DartType _getGetterType(PropertyAccessorElement getter) {
5706 FunctionType functionType = getter.type; 6308 FunctionType functionType = getter.type;
5707 if (functionType != null) { 6309 if (functionType != null) {
5708 return functionType.returnType; 6310 return functionType.returnType;
5709 } else { 6311 } else {
5710 return null; 6312 return null;
5711 } 6313 }
5712 } 6314 }
5713 6315
5714 /** 6316 /**
6317 * Return the name of the library that defines given [element].
6318 */
6319 String _getLibraryName(Element element) {
6320 if (element == null) {
6321 return StringUtilities.EMPTY;
6322 }
6323 LibraryElement library = element.library;
6324 if (library == null) {
6325 return StringUtilities.EMPTY;
6326 }
6327 List<ImportElement> imports = _currentLibrary.imports;
6328 int count = imports.length;
6329 for (int i = 0; i < count; i++) {
6330 if (identical(imports[i].importedLibrary, library)) {
6331 return library.definingCompilationUnit.displayName;
6332 }
6333 }
6334 List<String> indirectSources = new List<String>();
6335 for (int i = 0; i < count; i++) {
6336 LibraryElement importedLibrary = imports[i].importedLibrary;
6337 if (importedLibrary != null) {
6338 for (LibraryElement exportedLibrary
6339 in importedLibrary.exportedLibraries) {
6340 if (identical(exportedLibrary, library)) {
6341 indirectSources
6342 .add(importedLibrary.definingCompilationUnit.displayName);
6343 }
6344 }
6345 }
6346 }
6347 int indirectCount = indirectSources.length;
6348 StringBuffer buffer = new StringBuffer();
6349 buffer.write(library.definingCompilationUnit.displayName);
6350 if (indirectCount > 0) {
6351 buffer.write(" (via ");
6352 if (indirectCount > 1) {
6353 indirectSources.sort();
6354 buffer.write(StringUtilities.printListOfQuotedNames(indirectSources));
6355 } else {
6356 buffer.write(indirectSources[0]);
6357 }
6358 buffer.write(")");
6359 }
6360 return buffer.toString();
6361 }
6362
6363 ExecutableElement _getOverriddenMember(Element member) {
6364 if (member == null) {
6365 return null;
6366 }
6367 ClassElement classElement =
6368 member.getAncestor((element) => element is ClassElement);
6369 if (classElement == null) {
6370 return null;
6371 }
6372 String name = member.name;
6373 ClassElement superclass = classElement.supertype?.element;
6374 while (superclass != null) {
6375 ExecutableElement member = superclass.getMethod(name) ?? superclass.getGet ter(name) ?? superclass.getSetter(name);
6376 if (member != null) {
6377 return member;
6378 }
6379 superclass = superclass.supertype?.element;
6380 }
6381 return null;
6382 }
6383
6384 /**
5715 * Return the type of the first and only parameter of the given [setter]. 6385 * Return the type of the first and only parameter of the given [setter].
5716 */ 6386 */
5717 DartType _getSetterType(PropertyAccessorElement setter) { 6387 DartType _getSetterType(PropertyAccessorElement setter) {
5718 // Get the parameters for MethodDeclaration or FunctionDeclaration 6388 // Get the parameters for MethodDeclaration or FunctionDeclaration
5719 List<ParameterElement> setterParameters = setter.parameters; 6389 List<ParameterElement> setterParameters = setter.parameters;
5720 // If there are no setter parameters, return no type. 6390 // If there are no setter parameters, return no type.
5721 if (setterParameters.length == 0) { 6391 if (setterParameters.length == 0) {
5722 return null; 6392 return null;
5723 } 6393 }
5724 return setterParameters[0].type; 6394 return setterParameters[0].type;
5725 } 6395 }
5726 6396
5727 /** 6397 /**
5728 * Given a list of [directives] that have the same prefix, generate an error
5729 * if there is more than one import and any of those imports is deferred.
5730 *
5731 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX].
5732 */
5733 bool _hasDeferredPrefixCollision(List<ImportDirective> directives) {
5734 bool foundError = false;
5735 int count = directives.length;
5736 if (count > 1) {
5737 for (int i = 0; i < count; i++) {
5738 sc.Token deferredToken = directives[i].deferredKeyword;
5739 if (deferredToken != null) {
5740 _errorReporter.reportErrorForToken(
5741 CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken);
5742 foundError = true;
5743 }
5744 }
5745 }
5746 return foundError;
5747 }
5748
5749 /**
5750 * Return `true` if the given [constructor] redirects to itself, directly or 6398 * Return `true` if the given [constructor] redirects to itself, directly or
5751 * indirectly. 6399 * indirectly.
5752 */ 6400 */
5753 bool _hasRedirectingFactoryConstructorCycle(ConstructorElement constructor) { 6401 bool _hasRedirectingFactoryConstructorCycle(ConstructorElement constructor) {
6402 ConstructorElement nonMember(ConstructorElement constructor) {
6403 return constructor is ConstructorMember
6404 ? constructor.baseElement
6405 : constructor;
6406 }
6407
5754 Set<ConstructorElement> constructors = new HashSet<ConstructorElement>(); 6408 Set<ConstructorElement> constructors = new HashSet<ConstructorElement>();
5755 ConstructorElement current = constructor; 6409 ConstructorElement current = constructor;
5756 while (current != null) { 6410 while (current != null) {
5757 if (constructors.contains(current)) { 6411 if (constructors.contains(current)) {
5758 return identical(current, constructor); 6412 return identical(current, constructor);
5759 } 6413 }
5760 constructors.add(current); 6414 constructors.add(current);
5761 current = current.redirectedConstructor; 6415 current = nonMember(current.redirectedConstructor);
5762 if (current is ConstructorMember) {
5763 current = (current as ConstructorMember).baseElement;
5764 }
5765 } 6416 }
5766 return false; 6417 return false;
5767 } 6418 }
5768 6419
5769 /** 6420 /**
5770 * Return `true` if the given [element] has direct or indirect reference to 6421 * Return `true` if the given [element] has direct or indirect reference to
5771 * itself from anywhere except a class element or type parameter bounds. 6422 * itself from anywhere except a class element or type parameter bounds.
5772 */ 6423 */
5773 bool _hasTypedefSelfReference(Element element) { 6424 bool _hasTypedefSelfReference(Element element) {
5774 Set<Element> checked = new HashSet<Element>(); 6425 Set<Element> checked = new HashSet<Element>();
5775 List<Element> toCheck = new List<Element>(); 6426 List<Element> toCheck = new List<Element>();
5776 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference elementVisi tor = 6427 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference
6428 elementVisitor =
5777 new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference( 6429 new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(
5778 toCheck); 6430 toCheck);
5779 toCheck.add(element); 6431 toCheck.add(element);
5780 bool firstIteration = true; 6432 bool firstIteration = true;
5781 while (true) { 6433 while (true) {
5782 Element current; 6434 Element current;
5783 // get next element 6435 // get next element
5784 while (true) { 6436 while (true) {
5785 // may be no more elements to check 6437 // may be no more elements to check
5786 if (toCheck.isEmpty) { 6438 if (toCheck.isEmpty) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
5828 * have to equal or be a subtype of the given executable element, this is due 6480 * have to equal or be a subtype of the given executable element, this is due
5829 * to the specific use where this method is used in 6481 * to the specific use where this method is used in
5830 * [_checkForNonAbstractClassInheritsAbstractMember]. 6482 * [_checkForNonAbstractClassInheritsAbstractMember].
5831 */ 6483 */
5832 bool _isMemberInClassOrMixin( 6484 bool _isMemberInClassOrMixin(
5833 ExecutableElement executableElement, ClassElement classElement) { 6485 ExecutableElement executableElement, ClassElement classElement) {
5834 ExecutableElement foundElt = null; 6486 ExecutableElement foundElt = null;
5835 String executableName = executableElement.name; 6487 String executableName = executableElement.name;
5836 if (executableElement is MethodElement) { 6488 if (executableElement is MethodElement) {
5837 foundElt = classElement.getMethod(executableName); 6489 foundElt = classElement.getMethod(executableName);
5838 if (foundElt != null && !(foundElt as MethodElement).isAbstract) { 6490 if (foundElt != null && !foundElt.isAbstract) {
5839 return true; 6491 return true;
5840 } 6492 }
5841 List<InterfaceType> mixins = classElement.mixins; 6493 List<InterfaceType> mixins = classElement.mixins;
5842 for (int i = 0; i < mixins.length && foundElt == null; i++) { 6494 for (int i = 0; i < mixins.length && foundElt == null; i++) {
5843 foundElt = mixins[i].getMethod(executableName); 6495 foundElt = mixins[i].getMethod(executableName);
5844 } 6496 }
5845 if (foundElt != null && !(foundElt as MethodElement).isAbstract) { 6497 if (foundElt != null && !foundElt.isAbstract) {
5846 return true; 6498 return true;
5847 } 6499 }
5848 } else if (executableElement is PropertyAccessorElement) { 6500 } else if (executableElement is PropertyAccessorElement) {
5849 PropertyAccessorElement propertyAccessorElement = executableElement; 6501 if (executableElement.isGetter) {
5850 if (propertyAccessorElement.isGetter) {
5851 foundElt = classElement.getGetter(executableName); 6502 foundElt = classElement.getGetter(executableName);
5852 } 6503 }
5853 if (foundElt == null && propertyAccessorElement.isSetter) { 6504 if (foundElt == null && executableElement.isSetter) {
5854 foundElt = classElement.getSetter(executableName); 6505 foundElt = classElement.getSetter(executableName);
5855 } 6506 }
5856 if (foundElt != null && 6507 if (foundElt != null &&
5857 !(foundElt as PropertyAccessorElement).isAbstract) { 6508 !(foundElt as PropertyAccessorElement).isAbstract) {
5858 return true; 6509 return true;
5859 } 6510 }
5860 List<InterfaceType> mixins = classElement.mixins; 6511 List<InterfaceType> mixins = classElement.mixins;
5861 for (int i = 0; i < mixins.length && foundElt == null; i++) { 6512 for (int i = 0; i < mixins.length && foundElt == null; i++) {
5862 foundElt = mixins[i].getGetter(executableName); 6513 foundElt = mixins[i].getGetter(executableName);
5863 if (foundElt == null) { 6514 if (foundElt == null) {
5864 foundElt = mixins[i].getSetter(executableName); 6515 foundElt = mixins[i].getSetter(executableName);
5865 } 6516 }
5866 } 6517 }
5867 if (foundElt != null && 6518 if (foundElt != null && !foundElt.isAbstract) {
5868 !(foundElt as PropertyAccessorElement).isAbstract) {
5869 return true; 6519 return true;
5870 } 6520 }
5871 } 6521 }
5872 return false; 6522 return false;
5873 } 6523 }
5874 6524
5875 /** 6525 /**
5876 * Return `true` if the given 'this' [expression] is in a valid context. 6526 * Return `true` if the given 'this' [expression] is in a valid context.
5877 */ 6527 */
5878 bool _isThisInValidContext(ThisExpression expression) { 6528 bool _isThisInValidContext(ThisExpression expression) {
5879 for (AstNode node = expression.parent; node != null; node = node.parent) { 6529 for (AstNode node = expression.parent; node != null; node = node.parent) {
5880 if (node is CompilationUnit) { 6530 if (node is CompilationUnit) {
5881 return false; 6531 return false;
5882 } 6532 } else if (node is ConstructorDeclaration) {
5883 if (node is ConstructorDeclaration) {
5884 return node.factoryKeyword == null; 6533 return node.factoryKeyword == null;
5885 } 6534 } else if (node is ConstructorInitializer) {
5886 if (node is ConstructorInitializer) {
5887 return false; 6535 return false;
5888 } 6536 } else if (node is MethodDeclaration) {
5889 if (node is MethodDeclaration) {
5890 return !node.isStatic; 6537 return !node.isStatic;
5891 } 6538 }
5892 } 6539 }
5893 return false; 6540 return false;
5894 } 6541 }
5895 6542
5896 /** 6543 /**
5897 * Return `true` if the given [identifier] is in a location where it is 6544 * Return `true` if the given [identifier] is in a location where it is
5898 * allowed to resolve to a static member of a supertype. 6545 * allowed to resolve to a static member of a supertype.
5899 */ 6546 */
5900 bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed( 6547 bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed(
5901 SimpleIdentifier identifier) { 6548 SimpleIdentifier identifier) {
5902 if (identifier.inDeclarationContext()) { 6549 if (identifier.inDeclarationContext()) {
5903 return true; 6550 return true;
5904 } 6551 }
5905 AstNode parent = identifier.parent; 6552 AstNode parent = identifier.parent;
5906 if (parent is ConstructorName || 6553 if (parent is Annotation) {
5907 parent is MethodInvocation || 6554 return identical(parent.constructorName, identifier);
5908 parent is PropertyAccess ||
5909 parent is SuperConstructorInvocation) {
5910 return true;
5911 }
5912 if (parent is PrefixedIdentifier &&
5913 identical(parent.identifier, identifier)) {
5914 return true;
5915 }
5916 if (parent is Annotation && identical(parent.constructorName, identifier)) {
5917 return true;
5918 } 6555 }
5919 if (parent is CommentReference) { 6556 if (parent is CommentReference) {
5920 CommentReference commentReference = parent; 6557 return parent.newKeyword != null;
5921 if (commentReference.newKeyword != null) { 6558 }
5922 return true; 6559 if (parent is ConstructorName) {
5923 } 6560 return identical(parent.name, identifier);
6561 }
6562 if (parent is MethodInvocation) {
6563 return identical(parent.methodName, identifier);
6564 }
6565 if (parent is PrefixedIdentifier) {
6566 return identical(parent.identifier, identifier);
6567 }
6568 if (parent is PropertyAccess) {
6569 return identical(parent.propertyName, identifier);
6570 }
6571 if (parent is SuperConstructorInvocation) {
6572 return identical(parent.constructorName, identifier);
5924 } 6573 }
5925 return false; 6574 return false;
5926 } 6575 }
5927 6576
5928 bool _isUserDefinedObject(EvaluationResultImpl result) => result == null || 6577 bool _isUserDefinedObject(EvaluationResultImpl result) =>
6578 result == null ||
5929 (result.value != null && result.value.isUserDefinedObject); 6579 (result.value != null && result.value.isUserDefinedObject);
5930 6580
5931 /** 6581 /**
5932 * Check that the given class [element] is not a superinterface to itself. The 6582 * Check that the given class [element] is not a superinterface to itself. The
5933 * [path] is a list containing the potentially cyclic implements path. 6583 * [path] is a list containing the potentially cyclic implements path.
5934 * 6584 *
5935 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], 6585 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE],
5936 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], 6586 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS],
5937 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS] , 6587 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS] ,
5938 * and [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH]. 6588 * and [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH].
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
6031 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(this.toCheck) 6681 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(this.toCheck)
6032 : super(); 6682 : super();
6033 6683
6034 @override 6684 @override
6035 Object visitClassElement(ClassElement element) { 6685 Object visitClassElement(ClassElement element) {
6036 // Typedefs are allowed to reference themselves via classes. 6686 // Typedefs are allowed to reference themselves via classes.
6037 return null; 6687 return null;
6038 } 6688 }
6039 6689
6040 @override 6690 @override
6691 Object visitFunctionElement(FunctionElement element) {
6692 _addTypeToCheck(element.returnType);
6693 return super.visitFunctionElement(element);
6694 }
6695
6696 @override
6041 Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { 6697 Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
6042 _addTypeToCheck(element.returnType); 6698 _addTypeToCheck(element.returnType);
6043 return super.visitFunctionTypeAliasElement(element); 6699 return super.visitFunctionTypeAliasElement(element);
6044 } 6700 }
6045 6701
6046 @override 6702 @override
6047 Object visitParameterElement(ParameterElement element) { 6703 Object visitParameterElement(ParameterElement element) {
6048 _addTypeToCheck(element.type); 6704 _addTypeToCheck(element.type);
6049 return super.visitParameterElement(element); 6705 return super.visitParameterElement(element);
6050 } 6706 }
6051 6707
6052 @override 6708 @override
6053 Object visitTypeParameterElement(TypeParameterElement element) { 6709 Object visitTypeParameterElement(TypeParameterElement element) {
6054 _addTypeToCheck(element.bound); 6710 _addTypeToCheck(element.bound);
6055 return super.visitTypeParameterElement(element); 6711 return super.visitTypeParameterElement(element);
6056 } 6712 }
6057 6713
6058 void _addTypeToCheck(DartType type) { 6714 void _addTypeToCheck(DartType type) {
6059 if (type == null) { 6715 if (type == null) {
6060 return; 6716 return;
6061 } 6717 }
6062 // schedule for checking 6718 // schedule for checking
6063 toCheck.add(type.element); 6719 toCheck.add(type.element);
6064 // type arguments 6720 // type arguments
6065 if (type is InterfaceType) { 6721 if (type is InterfaceType) {
6066 InterfaceType interfaceType = type; 6722 for (DartType typeArgument in type.typeArguments) {
6067 for (DartType typeArgument in interfaceType.typeArguments) {
6068 _addTypeToCheck(typeArgument); 6723 _addTypeToCheck(typeArgument);
6069 } 6724 }
6070 } 6725 }
6071 } 6726 }
6072 } 6727 }
6728
6729 /**
6730 * A record of the elements that will be declared in some scope (block), but are
6731 * not yet declared.
6732 */
6733 class HiddenElements {
6734 /**
6735 * The elements hidden in outer scopes, or `null` if this is the outermost
6736 * scope.
6737 */
6738 final HiddenElements outerElements;
6739
6740 /**
6741 * A set containing the elements that will be declared in this scope, but are
6742 * not yet declared.
6743 */
6744 Set<Element> _elements = new HashSet<Element>();
6745
6746 /**
6747 * Initialize a newly created set of hidden elements to include all of the
6748 * elements defined in the set of [outerElements] and all of the elements
6749 * declared in the given [block].
6750 */
6751 HiddenElements(this.outerElements, Block block) {
6752 _initializeElements(block);
6753 }
6754
6755 /**
6756 * Return `true` if this set of elements contains the given [element].
6757 */
6758 bool contains(Element element) {
6759 if (_elements.contains(element)) {
6760 return true;
6761 } else if (outerElements != null) {
6762 return outerElements.contains(element);
6763 }
6764 return false;
6765 }
6766
6767 /**
6768 * Record that the given [element] has been declared, so it is no longer
6769 * hidden.
6770 */
6771 void declare(Element element) {
6772 _elements.remove(element);
6773 }
6774
6775 /**
6776 * Initialize the list of elements that are not yet declared to be all of the
6777 * elements declared somewhere in the given [block].
6778 */
6779 void _initializeElements(Block block) {
6780 _elements.addAll(BlockScope.elementsInBlock(block));
6781 }
6782 }
6783
6784 /**
6785 * A class used to compute a list of the constants whose value needs to be
6786 * computed before errors can be computed by the [VerifyUnitTask].
6787 */
6788 class RequiredConstantsComputer extends RecursiveAstVisitor {
6789 /**
6790 * The source with which any pending errors will be associated.
6791 */
6792 final Source source;
6793
6794 /**
6795 * A list of the pending errors that were computed.
6796 */
6797 final List<PendingError> pendingErrors = <PendingError>[];
6798
6799 /**
6800 * A list of the constants whose value needs to be computed before the pending
6801 * errors can be used to compute an analysis error.
6802 */
6803 final List<ConstantEvaluationTarget> requiredConstants =
6804 <ConstantEvaluationTarget>[];
6805
6806 /**
6807 * Initialize a newly created computer to compute required constants within
6808 * the given [source].
6809 */
6810 RequiredConstantsComputer(this.source);
6811
6812 @override
6813 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
6814 _checkForMissingRequiredParam(
6815 node.staticInvokeType, node.argumentList, node);
6816 return super.visitFunctionExpressionInvocation(node);
6817 }
6818
6819 @override
6820 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
6821 DartType type = node.constructorName.type.type;
6822 if (type is InterfaceType) {
6823 _checkForMissingRequiredParam(
6824 node.staticElement?.type, node.argumentList, node.constructorName);
6825 }
6826 return super.visitInstanceCreationExpression(node);
6827 }
6828
6829 @override
6830 Object visitMethodInvocation(MethodInvocation node) {
6831 _checkForMissingRequiredParam(
6832 node.staticInvokeType, node.argumentList, node.methodName);
6833 return super.visitMethodInvocation(node);
6834 }
6835
6836 @override
6837 Object visitRedirectingConstructorInvocation(
6838 RedirectingConstructorInvocation node) {
6839 DartType type = node.staticElement?.type;
6840 if (type != null) {
6841 _checkForMissingRequiredParam(type, node.argumentList, node);
6842 }
6843 return super.visitRedirectingConstructorInvocation(node);
6844 }
6845
6846 @override
6847 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
6848 DartType type = node.staticElement?.type;
6849 if (type != null) {
6850 _checkForMissingRequiredParam(type, node.argumentList, node);
6851 }
6852 return super.visitSuperConstructorInvocation(node);
6853 }
6854
6855 void _checkForMissingRequiredParam(
6856 DartType type, ArgumentList argumentList, AstNode node) {
6857 if (type is FunctionType) {
6858 for (ParameterElement parameter in type.parameters) {
6859 if (parameter.parameterKind == ParameterKind.NAMED) {
6860 ElementAnnotationImpl annotation = _getRequiredAnnotation(parameter);
6861 if (annotation != null) {
6862 String parameterName = parameter.name;
6863 if (!_containsNamedExpression(argumentList, parameterName)) {
6864 requiredConstants.add(annotation);
6865 pendingErrors.add(new PendingMissingRequiredParameterError(
6866 source, parameterName, node, annotation));
6867 }
6868 }
6869 }
6870 }
6871 }
6872 }
6873
6874 bool _containsNamedExpression(ArgumentList args, String name) {
6875 NodeList<Expression> arguments = args.arguments;
6876 for (int i = arguments.length - 1; i >= 0; i--) {
6877 Expression expression = arguments[i];
6878 if (expression is NamedExpression) {
6879 if (expression.name.label.name == name) {
6880 return true;
6881 }
6882 }
6883 }
6884 return false;
6885 }
6886
6887 ElementAnnotationImpl _getRequiredAnnotation(ParameterElement param) => param
6888 .metadata
6889 .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null);
6890 }
6891
6892 /**
6893 * Recursively visits an AST, looking for method invocations.
6894 */
6895 class _InvocationCollector extends RecursiveAstVisitor {
6896 final List<String> superCalls = <String>[];
6897
6898 @override
6899 visitMethodInvocation(MethodInvocation node) {
6900 if (node.target is SuperExpression) {
6901 superCalls.add(node.methodName.name);
6902 }
6903 }
6904 }
OLDNEW
« no previous file with comments | « packages/analyzer/lib/src/generated/error.dart ('k') | packages/analyzer/lib/src/generated/html.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698