OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library engine.resolver.error_verifier; | 5 library engine.resolver.error_verifier; |
6 | 6 |
7 import "dart:math" as math; | 7 import "dart:math" as math; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 | 9 |
10 import 'package:analyzer/src/generated/static_type_analyzer.dart'; | 10 import 'package:analyzer/src/generated/static_type_analyzer.dart'; |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 _isEnclosingConstructorConst = false; | 258 _isEnclosingConstructorConst = false; |
259 _isInCatchClause = false; | 259 _isInCatchClause = false; |
260 _isInStaticVariableDeclaration = false; | 260 _isInStaticVariableDeclaration = false; |
261 _isInInstanceVariableDeclaration = false; | 261 _isInInstanceVariableDeclaration = false; |
262 _isInInstanceVariableInitializer = false; | 262 _isInInstanceVariableInitializer = false; |
263 _isInConstructorInitializer = false; | 263 _isInConstructorInitializer = false; |
264 _isInStaticMethod = false; | 264 _isInStaticMethod = false; |
265 _boolType = _typeProvider.boolType; | 265 _boolType = _typeProvider.boolType; |
266 _intType = _typeProvider.intType; | 266 _intType = _typeProvider.intType; |
267 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = <InterfaceType>[ | 267 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = <InterfaceType>[ |
268 _typeProvider.nullType, | 268 _typeProvider.nullType, |
269 _typeProvider.numType, | 269 _typeProvider.numType, |
270 _intType, | 270 _intType, |
271 _typeProvider.doubleType, | 271 _typeProvider.doubleType, |
272 _boolType, | 272 _boolType, |
273 _typeProvider.stringType]; | 273 _typeProvider.stringType |
| 274 ]; |
274 } | 275 } |
275 | 276 |
276 @override | 277 @override |
277 Object visitAnnotation(Annotation node) { | 278 Object visitAnnotation(Annotation node) { |
278 _checkForInvalidAnnotationFromDeferredLibrary(node); | 279 _checkForInvalidAnnotationFromDeferredLibrary(node); |
279 return super.visitAnnotation(node); | 280 return super.visitAnnotation(node); |
280 } | 281 } |
281 | 282 |
282 @override | 283 @override |
283 Object visitArgumentList(ArgumentList node) { | 284 Object visitArgumentList(ArgumentList node) { |
(...skipping 25 matching lines...) Expand all Loading... |
309 _checkForArgumentTypeNotAssignableForArgument(rhs); | 310 _checkForArgumentTypeNotAssignableForArgument(rhs); |
310 } | 311 } |
311 _checkForAssignmentToFinal(lhs); | 312 _checkForAssignmentToFinal(lhs); |
312 return super.visitAssignmentExpression(node); | 313 return super.visitAssignmentExpression(node); |
313 } | 314 } |
314 | 315 |
315 @override | 316 @override |
316 Object visitAwaitExpression(AwaitExpression node) { | 317 Object visitAwaitExpression(AwaitExpression node) { |
317 if (!_inAsync) { | 318 if (!_inAsync) { |
318 _errorReporter.reportErrorForToken( | 319 _errorReporter.reportErrorForToken( |
319 CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, | 320 CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, node.awaitKeyword); |
320 node.awaitKeyword); | |
321 } | 321 } |
322 return super.visitAwaitExpression(node); | 322 return super.visitAwaitExpression(node); |
323 } | 323 } |
324 | 324 |
325 @override | 325 @override |
326 Object visitBinaryExpression(BinaryExpression node) { | 326 Object visitBinaryExpression(BinaryExpression node) { |
327 sc.Token operator = node.operator; | 327 sc.Token operator = node.operator; |
328 sc.TokenType type = operator.type; | 328 sc.TokenType type = operator.type; |
329 if (type == sc.TokenType.AMPERSAND_AMPERSAND || | 329 if (type == sc.TokenType.AMPERSAND_AMPERSAND || |
330 type == sc.TokenType.BAR_BAR) { | 330 type == sc.TokenType.BAR_BAR) { |
331 String lexeme = operator.lexeme; | 331 String lexeme = operator.lexeme; |
332 _checkForAssignability( | 332 _checkForAssignability(node.leftOperand, _boolType, |
333 node.leftOperand, | 333 StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]); |
334 _boolType, | 334 _checkForAssignability(node.rightOperand, _boolType, |
335 StaticTypeWarningCode.NON_BOOL_OPERAND, | 335 StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]); |
336 [lexeme]); | |
337 _checkForAssignability( | |
338 node.rightOperand, | |
339 _boolType, | |
340 StaticTypeWarningCode.NON_BOOL_OPERAND, | |
341 [lexeme]); | |
342 } else { | 336 } else { |
343 _checkForArgumentTypeNotAssignableForArgument(node.rightOperand); | 337 _checkForArgumentTypeNotAssignableForArgument(node.rightOperand); |
344 } | 338 } |
345 return super.visitBinaryExpression(node); | 339 return super.visitBinaryExpression(node); |
346 } | 340 } |
347 | 341 |
348 @override | 342 @override |
349 Object visitBlockFunctionBody(BlockFunctionBody node) { | 343 Object visitBlockFunctionBody(BlockFunctionBody node) { |
350 bool wasInAsync = _inAsync; | 344 bool wasInAsync = _inAsync; |
351 bool wasInGenerator = _inGenerator; | 345 bool wasInGenerator = _inGenerator; |
(...skipping 18 matching lines...) Expand all Loading... |
370 return null; | 364 return null; |
371 } | 365 } |
372 | 366 |
373 @override | 367 @override |
374 Object visitBreakStatement(BreakStatement node) { | 368 Object visitBreakStatement(BreakStatement node) { |
375 SimpleIdentifier labelNode = node.label; | 369 SimpleIdentifier labelNode = node.label; |
376 if (labelNode != null) { | 370 if (labelNode != null) { |
377 Element labelElement = labelNode.staticElement; | 371 Element labelElement = labelNode.staticElement; |
378 if (labelElement is LabelElementImpl && labelElement.isOnSwitchMember) { | 372 if (labelElement is LabelElementImpl && labelElement.isOnSwitchMember) { |
379 _errorReporter.reportErrorForNode( | 373 _errorReporter.reportErrorForNode( |
380 ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, | 374 ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode); |
381 labelNode); | |
382 } | 375 } |
383 } | 376 } |
384 return null; | 377 return null; |
385 } | 378 } |
386 | 379 |
387 @override | 380 @override |
388 Object visitCatchClause(CatchClause node) { | 381 Object visitCatchClause(CatchClause node) { |
389 bool previousIsInCatchClause = _isInCatchClause; | 382 bool previousIsInCatchClause = _isInCatchClause; |
390 try { | 383 try { |
391 _isInCatchClause = true; | 384 _isInCatchClause = true; |
392 _checkForTypeAnnotationDeferredClass(node.exceptionType); | 385 _checkForTypeAnnotationDeferredClass(node.exceptionType); |
393 return super.visitCatchClause(node); | 386 return super.visitCatchClause(node); |
394 } finally { | 387 } finally { |
395 _isInCatchClause = previousIsInCatchClause; | 388 _isInCatchClause = previousIsInCatchClause; |
396 } | 389 } |
397 } | 390 } |
398 | 391 |
399 @override | 392 @override |
400 Object visitClassDeclaration(ClassDeclaration node) { | 393 Object visitClassDeclaration(ClassDeclaration node) { |
401 ClassElement outerClass = _enclosingClass; | 394 ClassElement outerClass = _enclosingClass; |
402 try { | 395 try { |
403 _isInNativeClass = node.nativeClause != null; | 396 _isInNativeClass = node.nativeClause != null; |
404 _enclosingClass = node.element; | 397 _enclosingClass = node.element; |
405 ExtendsClause extendsClause = node.extendsClause; | 398 ExtendsClause extendsClause = node.extendsClause; |
406 ImplementsClause implementsClause = node.implementsClause; | 399 ImplementsClause implementsClause = node.implementsClause; |
407 WithClause withClause = node.withClause; | 400 WithClause withClause = node.withClause; |
408 _checkForBuiltInIdentifierAsName( | 401 _checkForBuiltInIdentifierAsName( |
409 node.name, | 402 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME); |
410 CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME); | |
411 _checkForMemberWithClassName(); | 403 _checkForMemberWithClassName(); |
412 _checkForNoDefaultSuperConstructorImplicit(node); | 404 _checkForNoDefaultSuperConstructorImplicit(node); |
413 _checkForConflictingTypeVariableErrorCodes(node); | 405 _checkForConflictingTypeVariableErrorCodes(node); |
414 // Only do error checks on the clause nodes if there is a non-null clause | 406 // Only do error checks on the clause nodes if there is a non-null clause |
415 if (implementsClause != null || | 407 if (implementsClause != null || |
416 extendsClause != null || | 408 extendsClause != null || |
417 withClause != null) { | 409 withClause != null) { |
418 // Only check for all of the inheritance logic around clauses if there | 410 // Only check for all of the inheritance logic around clauses if there |
419 // isn't an error code such as "Cannot extend double" already on the | 411 // isn't an error code such as "Cannot extend double" already on the |
420 // class. | 412 // class. |
(...skipping 29 matching lines...) Expand all Loading... |
450 */ | 442 */ |
451 visitClassDeclarationIncrementally(ClassDeclaration node) { | 443 visitClassDeclarationIncrementally(ClassDeclaration node) { |
452 _isInNativeClass = node.nativeClause != null; | 444 _isInNativeClass = node.nativeClause != null; |
453 _enclosingClass = node.element; | 445 _enclosingClass = node.element; |
454 // initialize initialFieldElementsMap | 446 // initialize initialFieldElementsMap |
455 if (_enclosingClass != null) { | 447 if (_enclosingClass != null) { |
456 List<FieldElement> fieldElements = _enclosingClass.fields; | 448 List<FieldElement> fieldElements = _enclosingClass.fields; |
457 _initialFieldElementsMap = new HashMap<FieldElement, INIT_STATE>(); | 449 _initialFieldElementsMap = new HashMap<FieldElement, INIT_STATE>(); |
458 for (FieldElement fieldElement in fieldElements) { | 450 for (FieldElement fieldElement in fieldElements) { |
459 if (!fieldElement.isSynthetic) { | 451 if (!fieldElement.isSynthetic) { |
460 _initialFieldElementsMap[fieldElement] = | 452 _initialFieldElementsMap[fieldElement] = fieldElement.initializer == |
461 fieldElement.initializer == null ? | 453 null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; |
462 INIT_STATE.NOT_INIT : | |
463 INIT_STATE.INIT_IN_DECLARATION; | |
464 } | 454 } |
465 } | 455 } |
466 } | 456 } |
467 } | 457 } |
468 | 458 |
469 @override | 459 @override |
470 Object visitClassTypeAlias(ClassTypeAlias node) { | 460 Object visitClassTypeAlias(ClassTypeAlias node) { |
471 _checkForBuiltInIdentifierAsName( | 461 _checkForBuiltInIdentifierAsName( |
472 node.name, | 462 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); |
473 CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); | |
474 ClassElement outerClassElement = _enclosingClass; | 463 ClassElement outerClassElement = _enclosingClass; |
475 try { | 464 try { |
476 _enclosingClass = node.element; | 465 _enclosingClass = node.element; |
477 ImplementsClause implementsClause = node.implementsClause; | 466 ImplementsClause implementsClause = node.implementsClause; |
478 // Only check for all of the inheritance logic around clauses if there | 467 // Only check for all of the inheritance logic around clauses if there |
479 // isn't an error code such as "Cannot extend double" already on the | 468 // isn't an error code such as "Cannot extend double" already on the |
480 // class. | 469 // class. |
481 if (!_checkForExtendsDisallowedClassInTypeAlias(node) && | 470 if (!_checkForExtendsDisallowedClassInTypeAlias(node) && |
482 !_checkForImplementsDisallowedClass(implementsClause) && | 471 !_checkForImplementsDisallowedClass(implementsClause) && |
483 !_checkForAllMixinErrorCodes(node.withClause)) { | 472 !_checkForAllMixinErrorCodes(node.withClause)) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 | 505 |
517 @override | 506 @override |
518 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 507 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
519 ExecutableElement outerFunction = _enclosingFunction; | 508 ExecutableElement outerFunction = _enclosingFunction; |
520 try { | 509 try { |
521 ConstructorElement constructorElement = node.element; | 510 ConstructorElement constructorElement = node.element; |
522 _enclosingFunction = constructorElement; | 511 _enclosingFunction = constructorElement; |
523 _isEnclosingConstructorConst = node.constKeyword != null; | 512 _isEnclosingConstructorConst = node.constKeyword != null; |
524 _isInFactory = node.factoryKeyword != null; | 513 _isInFactory = node.factoryKeyword != null; |
525 _checkForInvalidModifierOnBody( | 514 _checkForInvalidModifierOnBody( |
526 node.body, | 515 node.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR); |
527 CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR); | |
528 _checkForConstConstructorWithNonFinalField(node, constructorElement); | 516 _checkForConstConstructorWithNonFinalField(node, constructorElement); |
529 _checkForConstConstructorWithNonConstSuper(node); | 517 _checkForConstConstructorWithNonConstSuper(node); |
530 _checkForConflictingConstructorNameAndMember(node, constructorElement); | 518 _checkForConflictingConstructorNameAndMember(node, constructorElement); |
531 _checkForAllFinalInitializedErrorCodes(node); | 519 _checkForAllFinalInitializedErrorCodes(node); |
532 _checkForRedirectingConstructorErrorCodes(node); | 520 _checkForRedirectingConstructorErrorCodes(node); |
533 _checkForMultipleSuperInitializers(node); | 521 _checkForMultipleSuperInitializers(node); |
534 _checkForRecursiveConstructorRedirect(node, constructorElement); | 522 _checkForRecursiveConstructorRedirect(node, constructorElement); |
535 if (!_checkForRecursiveFactoryRedirect(node, constructorElement)) { | 523 if (!_checkForRecursiveFactoryRedirect(node, constructorElement)) { |
536 _checkForAllRedirectConstructorErrorCodes(node); | 524 _checkForAllRedirectConstructorErrorCodes(node); |
537 } | 525 } |
(...skipping 23 matching lines...) Expand all Loading... |
561 } | 549 } |
562 | 550 |
563 @override | 551 @override |
564 Object visitContinueStatement(ContinueStatement node) { | 552 Object visitContinueStatement(ContinueStatement node) { |
565 SimpleIdentifier labelNode = node.label; | 553 SimpleIdentifier labelNode = node.label; |
566 if (labelNode != null) { | 554 if (labelNode != null) { |
567 Element labelElement = labelNode.staticElement; | 555 Element labelElement = labelNode.staticElement; |
568 if (labelElement is LabelElementImpl && | 556 if (labelElement is LabelElementImpl && |
569 labelElement.isOnSwitchStatement) { | 557 labelElement.isOnSwitchStatement) { |
570 _errorReporter.reportErrorForNode( | 558 _errorReporter.reportErrorForNode( |
571 ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, | 559 ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode); |
572 labelNode); | |
573 } | 560 } |
574 } | 561 } |
575 return null; | 562 return null; |
576 } | 563 } |
577 | 564 |
578 @override | 565 @override |
579 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 566 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
580 _checkForInvalidAssignment(node.identifier, node.defaultValue); | 567 _checkForInvalidAssignment(node.identifier, node.defaultValue); |
581 _checkForDefaultValueInFunctionTypedParameter(node); | 568 _checkForDefaultValueInFunctionTypedParameter(node); |
582 return super.visitDefaultFormalParameter(node); | 569 return super.visitDefaultFormalParameter(node); |
(...skipping 19 matching lines...) Expand all Loading... |
602 | 589 |
603 @override | 590 @override |
604 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { | 591 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { |
605 bool wasInAsync = _inAsync; | 592 bool wasInAsync = _inAsync; |
606 bool wasInGenerator = _inGenerator; | 593 bool wasInGenerator = _inGenerator; |
607 try { | 594 try { |
608 _inAsync = node.isAsynchronous; | 595 _inAsync = node.isAsynchronous; |
609 _inGenerator = node.isGenerator; | 596 _inGenerator = node.isGenerator; |
610 FunctionType functionType = | 597 FunctionType functionType = |
611 _enclosingFunction == null ? null : _enclosingFunction.type; | 598 _enclosingFunction == null ? null : _enclosingFunction.type; |
612 DartType expectedReturnType = | 599 DartType expectedReturnType = functionType == null |
613 functionType == null ? DynamicTypeImpl.instance : functionType.returnT
ype; | 600 ? DynamicTypeImpl.instance |
| 601 : functionType.returnType; |
614 _checkForReturnOfInvalidType(node.expression, expectedReturnType); | 602 _checkForReturnOfInvalidType(node.expression, expectedReturnType); |
615 return super.visitExpressionFunctionBody(node); | 603 return super.visitExpressionFunctionBody(node); |
616 } finally { | 604 } finally { |
617 _inAsync = wasInAsync; | 605 _inAsync = wasInAsync; |
618 _inGenerator = wasInGenerator; | 606 _inGenerator = wasInGenerator; |
619 } | 607 } |
620 } | 608 } |
621 | 609 |
622 @override | 610 @override |
623 Object visitFieldDeclaration(FieldDeclaration node) { | 611 Object visitFieldDeclaration(FieldDeclaration node) { |
624 _isInStaticVariableDeclaration = node.isStatic; | 612 _isInStaticVariableDeclaration = node.isStatic; |
625 _isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration; | 613 _isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration; |
626 if (_isInInstanceVariableDeclaration) { | 614 if (_isInInstanceVariableDeclaration) { |
627 VariableDeclarationList variables = node.fields; | 615 VariableDeclarationList variables = node.fields; |
628 if (variables.isConst) { | 616 if (variables.isConst) { |
629 _errorReporter.reportErrorForToken( | 617 _errorReporter.reportErrorForToken( |
630 CompileTimeErrorCode.CONST_INSTANCE_FIELD, | 618 CompileTimeErrorCode.CONST_INSTANCE_FIELD, variables.keyword); |
631 variables.keyword); | |
632 } | 619 } |
633 } | 620 } |
634 try { | 621 try { |
635 _checkForAllInvalidOverrideErrorCodesForField(node); | 622 _checkForAllInvalidOverrideErrorCodesForField(node); |
636 return super.visitFieldDeclaration(node); | 623 return super.visitFieldDeclaration(node); |
637 } finally { | 624 } finally { |
638 _isInStaticVariableDeclaration = false; | 625 _isInStaticVariableDeclaration = false; |
639 _isInInstanceVariableDeclaration = false; | 626 _isInInstanceVariableDeclaration = false; |
640 } | 627 } |
641 } | 628 } |
(...skipping 18 matching lines...) Expand all Loading... |
660 methodName = identifier.name; | 647 methodName = identifier.name; |
661 } | 648 } |
662 _enclosingFunction = node.element; | 649 _enclosingFunction = node.element; |
663 TypeName returnType = node.returnType; | 650 TypeName returnType = node.returnType; |
664 if (node.isSetter || node.isGetter) { | 651 if (node.isSetter || node.isGetter) { |
665 _checkForMismatchedAccessorTypes(node, methodName); | 652 _checkForMismatchedAccessorTypes(node, methodName); |
666 if (node.isSetter) { | 653 if (node.isSetter) { |
667 FunctionExpression functionExpression = node.functionExpression; | 654 FunctionExpression functionExpression = node.functionExpression; |
668 if (functionExpression != null) { | 655 if (functionExpression != null) { |
669 _checkForWrongNumberOfParametersForSetter( | 656 _checkForWrongNumberOfParametersForSetter( |
670 identifier, | 657 identifier, functionExpression.parameters); |
671 functionExpression.parameters); | |
672 } | 658 } |
673 _checkForNonVoidReturnTypeForSetter(returnType); | 659 _checkForNonVoidReturnTypeForSetter(returnType); |
674 } | 660 } |
675 } | 661 } |
676 if (node.isSetter) { | 662 if (node.isSetter) { |
677 _checkForInvalidModifierOnBody( | 663 _checkForInvalidModifierOnBody(node.functionExpression.body, |
678 node.functionExpression.body, | |
679 CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER); | 664 CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER); |
680 } | 665 } |
681 _checkForTypeAnnotationDeferredClass(returnType); | 666 _checkForTypeAnnotationDeferredClass(returnType); |
682 _checkForIllegalReturnType(returnType); | 667 _checkForIllegalReturnType(returnType); |
683 return super.visitFunctionDeclaration(node); | 668 return super.visitFunctionDeclaration(node); |
684 } finally { | 669 } finally { |
685 _enclosingFunction = outerFunction; | 670 _enclosingFunction = outerFunction; |
686 } | 671 } |
687 } | 672 } |
688 | 673 |
(...skipping 22 matching lines...) Expand all Loading... |
711 _errorReporter.reportErrorForNode( | 696 _errorReporter.reportErrorForNode( |
712 StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, | 697 StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, |
713 functionExpression); | 698 functionExpression); |
714 } | 699 } |
715 return super.visitFunctionExpressionInvocation(node); | 700 return super.visitFunctionExpressionInvocation(node); |
716 } | 701 } |
717 | 702 |
718 @override | 703 @override |
719 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 704 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
720 _checkForBuiltInIdentifierAsName( | 705 _checkForBuiltInIdentifierAsName( |
721 node.name, | 706 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); |
722 CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); | |
723 _checkForDefaultValueInFunctionTypeAlias(node); | 707 _checkForDefaultValueInFunctionTypeAlias(node); |
724 _checkForTypeAliasCannotReferenceItself_function(node); | 708 _checkForTypeAliasCannotReferenceItself_function(node); |
725 return super.visitFunctionTypeAlias(node); | 709 return super.visitFunctionTypeAlias(node); |
726 } | 710 } |
727 | 711 |
728 @override | 712 @override |
729 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 713 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
730 bool old = _isInFunctionTypedFormalParameter; | 714 bool old = _isInFunctionTypedFormalParameter; |
731 _isInFunctionTypedFormalParameter = true; | 715 _isInFunctionTypedFormalParameter = true; |
732 try { | 716 try { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 ConstructorName constructorName = node.constructorName; | 751 ConstructorName constructorName = node.constructorName; |
768 TypeName typeName = constructorName.type; | 752 TypeName typeName = constructorName.type; |
769 DartType type = typeName.type; | 753 DartType type = typeName.type; |
770 if (type is InterfaceType) { | 754 if (type is InterfaceType) { |
771 InterfaceType interfaceType = type; | 755 InterfaceType interfaceType = type; |
772 _checkForConstOrNewWithAbstractClass(node, typeName, interfaceType); | 756 _checkForConstOrNewWithAbstractClass(node, typeName, interfaceType); |
773 _checkForConstOrNewWithEnum(node, typeName, interfaceType); | 757 _checkForConstOrNewWithEnum(node, typeName, interfaceType); |
774 if (_isInConstInstanceCreation) { | 758 if (_isInConstInstanceCreation) { |
775 _checkForConstWithNonConst(node); | 759 _checkForConstWithNonConst(node); |
776 _checkForConstWithUndefinedConstructor( | 760 _checkForConstWithUndefinedConstructor( |
777 node, | 761 node, constructorName, typeName); |
778 constructorName, | |
779 typeName); | |
780 _checkForConstWithTypeParameters(typeName); | 762 _checkForConstWithTypeParameters(typeName); |
781 _checkForConstDeferredClass(node, constructorName, typeName); | 763 _checkForConstDeferredClass(node, constructorName, typeName); |
782 } else { | 764 } else { |
783 _checkForNewWithUndefinedConstructor(node, constructorName, typeName); | 765 _checkForNewWithUndefinedConstructor(node, constructorName, typeName); |
784 } | 766 } |
785 } | 767 } |
786 return super.visitInstanceCreationExpression(node); | 768 return super.visitInstanceCreationExpression(node); |
787 } finally { | 769 } finally { |
788 _isInConstInstanceCreation = wasInConstInstanceCreation; | 770 _isInConstInstanceCreation = wasInConstInstanceCreation; |
789 } | 771 } |
790 } | 772 } |
791 | 773 |
792 @override | 774 @override |
793 Object visitIsExpression(IsExpression node) { | 775 Object visitIsExpression(IsExpression node) { |
794 _checkForTypeAnnotationDeferredClass(node.type); | 776 _checkForTypeAnnotationDeferredClass(node.type); |
795 return super.visitIsExpression(node); | 777 return super.visitIsExpression(node); |
796 } | 778 } |
797 | 779 |
798 @override | 780 @override |
799 Object visitListLiteral(ListLiteral node) { | 781 Object visitListLiteral(ListLiteral node) { |
800 TypeArgumentList typeArguments = node.typeArguments; | 782 TypeArgumentList typeArguments = node.typeArguments; |
801 if (typeArguments != null) { | 783 if (typeArguments != null) { |
802 if (node.constKeyword != null) { | 784 if (node.constKeyword != null) { |
803 NodeList<TypeName> arguments = typeArguments.arguments; | 785 NodeList<TypeName> arguments = typeArguments.arguments; |
804 if (arguments.length != 0) { | 786 if (arguments.length != 0) { |
805 _checkForInvalidTypeArgumentInConstTypedLiteral( | 787 _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, |
806 arguments, | |
807 CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST); | 788 CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST); |
808 } | 789 } |
809 } | 790 } |
810 _checkForExpectedOneListTypeArgument(node, typeArguments); | 791 _checkForExpectedOneListTypeArgument(node, typeArguments); |
811 _checkForListElementTypeNotAssignable(node, typeArguments); | 792 _checkForListElementTypeNotAssignable(node, typeArguments); |
812 } | 793 } |
813 return super.visitListLiteral(node); | 794 return super.visitListLiteral(node); |
814 } | 795 } |
815 | 796 |
816 @override | 797 @override |
817 Object visitMapLiteral(MapLiteral node) { | 798 Object visitMapLiteral(MapLiteral node) { |
818 TypeArgumentList typeArguments = node.typeArguments; | 799 TypeArgumentList typeArguments = node.typeArguments; |
819 if (typeArguments != null) { | 800 if (typeArguments != null) { |
820 NodeList<TypeName> arguments = typeArguments.arguments; | 801 NodeList<TypeName> arguments = typeArguments.arguments; |
821 if (arguments.length != 0) { | 802 if (arguments.length != 0) { |
822 if (node.constKeyword != null) { | 803 if (node.constKeyword != null) { |
823 _checkForInvalidTypeArgumentInConstTypedLiteral( | 804 _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, |
824 arguments, | |
825 CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP); | 805 CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP); |
826 } | 806 } |
827 } | 807 } |
828 _checkExpectedTwoMapTypeArguments(typeArguments); | 808 _checkExpectedTwoMapTypeArguments(typeArguments); |
829 _checkForMapTypeNotAssignable(node, typeArguments); | 809 _checkForMapTypeNotAssignable(node, typeArguments); |
830 } | 810 } |
831 _checkForNonConstMapAsExpressionStatement(node); | 811 _checkForNonConstMapAsExpressionStatement(node); |
832 return super.visitMapLiteral(node); | 812 return super.visitMapLiteral(node); |
833 } | 813 } |
834 | 814 |
(...skipping 10 matching lines...) Expand all Loading... |
845 } | 825 } |
846 TypeName returnTypeName = node.returnType; | 826 TypeName returnTypeName = node.returnType; |
847 if (node.isSetter || node.isGetter) { | 827 if (node.isSetter || node.isGetter) { |
848 _checkForMismatchedAccessorTypes(node, methodName); | 828 _checkForMismatchedAccessorTypes(node, methodName); |
849 } | 829 } |
850 if (node.isGetter) { | 830 if (node.isGetter) { |
851 _checkForVoidReturnType(node); | 831 _checkForVoidReturnType(node); |
852 _checkForConflictingStaticGetterAndInstanceSetter(node); | 832 _checkForConflictingStaticGetterAndInstanceSetter(node); |
853 } else if (node.isSetter) { | 833 } else if (node.isSetter) { |
854 _checkForInvalidModifierOnBody( | 834 _checkForInvalidModifierOnBody( |
855 node.body, | 835 node.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER); |
856 CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER); | |
857 _checkForWrongNumberOfParametersForSetter(node.name, node.parameters); | 836 _checkForWrongNumberOfParametersForSetter(node.name, node.parameters); |
858 _checkForNonVoidReturnTypeForSetter(returnTypeName); | 837 _checkForNonVoidReturnTypeForSetter(returnTypeName); |
859 _checkForConflictingStaticSetterAndInstanceMember(node); | 838 _checkForConflictingStaticSetterAndInstanceMember(node); |
860 } else if (node.isOperator) { | 839 } else if (node.isOperator) { |
861 _checkForOptionalParameterInOperator(node); | 840 _checkForOptionalParameterInOperator(node); |
862 _checkForWrongNumberOfParametersForOperator(node); | 841 _checkForWrongNumberOfParametersForOperator(node); |
863 _checkForNonVoidReturnTypeForOperator(node); | 842 _checkForNonVoidReturnTypeForOperator(node); |
864 } | 843 } |
865 _checkForConcreteClassWithAbstractMember(node); | 844 _checkForConcreteClassWithAbstractMember(node); |
866 _checkForAllInvalidOverrideErrorCodesForMethod(node); | 845 _checkForAllInvalidOverrideErrorCodesForMethod(node); |
(...skipping 19 matching lines...) Expand all Loading... |
886 } | 865 } |
887 return super.visitMethodInvocation(node); | 866 return super.visitMethodInvocation(node); |
888 } | 867 } |
889 | 868 |
890 @override | 869 @override |
891 Object visitNativeClause(NativeClause node) { | 870 Object visitNativeClause(NativeClause node) { |
892 // TODO(brianwilkerson) Figure out the right rule for when 'native' is | 871 // TODO(brianwilkerson) Figure out the right rule for when 'native' is |
893 // allowed. | 872 // allowed. |
894 if (!_isInSystemLibrary) { | 873 if (!_isInSystemLibrary) { |
895 _errorReporter.reportErrorForNode( | 874 _errorReporter.reportErrorForNode( |
896 ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, | 875 ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node); |
897 node); | |
898 } | 876 } |
899 return super.visitNativeClause(node); | 877 return super.visitNativeClause(node); |
900 } | 878 } |
901 | 879 |
902 @override | 880 @override |
903 Object visitNativeFunctionBody(NativeFunctionBody node) { | 881 Object visitNativeFunctionBody(NativeFunctionBody node) { |
904 _checkForNativeFunctionBodyInNonSDKCode(node); | 882 _checkForNativeFunctionBodyInNonSDKCode(node); |
905 return super.visitNativeFunctionBody(node); | 883 return super.visitNativeFunctionBody(node); |
906 } | 884 } |
907 | 885 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 Object visitPropertyAccess(PropertyAccess node) { | 919 Object visitPropertyAccess(PropertyAccess node) { |
942 ClassElement typeReference = | 920 ClassElement typeReference = |
943 ElementResolver.getTypeReference(node.realTarget); | 921 ElementResolver.getTypeReference(node.realTarget); |
944 SimpleIdentifier propertyName = node.propertyName; | 922 SimpleIdentifier propertyName = node.propertyName; |
945 _checkForStaticAccessToInstanceMember(typeReference, propertyName); | 923 _checkForStaticAccessToInstanceMember(typeReference, propertyName); |
946 _checkForInstanceAccessToStaticMember(typeReference, propertyName); | 924 _checkForInstanceAccessToStaticMember(typeReference, propertyName); |
947 return super.visitPropertyAccess(node); | 925 return super.visitPropertyAccess(node); |
948 } | 926 } |
949 | 927 |
950 @override | 928 @override |
951 Object | 929 Object visitRedirectingConstructorInvocation( |
952 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation nod
e) { | 930 RedirectingConstructorInvocation node) { |
953 _isInConstructorInitializer = true; | 931 _isInConstructorInitializer = true; |
954 try { | 932 try { |
955 return super.visitRedirectingConstructorInvocation(node); | 933 return super.visitRedirectingConstructorInvocation(node); |
956 } finally { | 934 } finally { |
957 _isInConstructorInitializer = false; | 935 _isInConstructorInitializer = false; |
958 } | 936 } |
959 } | 937 } |
960 | 938 |
961 @override | 939 @override |
962 Object visitRethrowExpression(RethrowExpression node) { | 940 Object visitRethrowExpression(RethrowExpression node) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 | 1017 |
1040 @override | 1018 @override |
1041 Object visitTypeName(TypeName node) { | 1019 Object visitTypeName(TypeName node) { |
1042 _checkForTypeArgumentNotMatchingBounds(node); | 1020 _checkForTypeArgumentNotMatchingBounds(node); |
1043 _checkForTypeParameterReferencedByStatic(node); | 1021 _checkForTypeParameterReferencedByStatic(node); |
1044 return super.visitTypeName(node); | 1022 return super.visitTypeName(node); |
1045 } | 1023 } |
1046 | 1024 |
1047 @override | 1025 @override |
1048 Object visitTypeParameter(TypeParameter node) { | 1026 Object visitTypeParameter(TypeParameter node) { |
1049 _checkForBuiltInIdentifierAsName( | 1027 _checkForBuiltInIdentifierAsName(node.name, |
1050 node.name, | |
1051 CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME); | 1028 CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME); |
1052 _checkForTypeParameterSupertypeOfItsBound(node); | 1029 _checkForTypeParameterSupertypeOfItsBound(node); |
1053 _checkForTypeAnnotationDeferredClass(node.bound); | 1030 _checkForTypeAnnotationDeferredClass(node.bound); |
1054 return super.visitTypeParameter(node); | 1031 return super.visitTypeParameter(node); |
1055 } | 1032 } |
1056 | 1033 |
1057 @override | 1034 @override |
1058 Object visitVariableDeclaration(VariableDeclaration node) { | 1035 Object visitVariableDeclaration(VariableDeclaration node) { |
1059 SimpleIdentifier nameNode = node.name; | 1036 SimpleIdentifier nameNode = node.name; |
1060 Expression initializerNode = node.initializer; | 1037 Expression initializerNode = node.initializer; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1121 * See [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]. | 1098 * See [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]. |
1122 */ | 1099 */ |
1123 bool _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { | 1100 bool _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { |
1124 // check number of type arguments | 1101 // check number of type arguments |
1125 int num = typeArguments.arguments.length; | 1102 int num = typeArguments.arguments.length; |
1126 if (num == 2) { | 1103 if (num == 2) { |
1127 return false; | 1104 return false; |
1128 } | 1105 } |
1129 // report problem | 1106 // report problem |
1130 _errorReporter.reportErrorForNode( | 1107 _errorReporter.reportErrorForNode( |
1131 StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, | 1108 StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArguments, [ |
1132 typeArguments, | 1109 num |
1133 [num]); | 1110 ]); |
1134 return true; | 1111 return true; |
1135 } | 1112 } |
1136 | 1113 |
1137 /** | 1114 /** |
1138 * This verifies that the passed constructor declaration does not violate any
of the error codes | 1115 * This verifies that the passed constructor declaration does not violate any
of the error codes |
1139 * relating to the initialization of fields in the enclosing class. | 1116 * relating to the initialization of fields in the enclosing class. |
1140 * | 1117 * |
1141 * @param node the [ConstructorDeclaration] to evaluate | 1118 * @param node the [ConstructorDeclaration] to evaluate |
1142 * @return `true` if and only if an error code is generated on the passed node | 1119 * @return `true` if and only if an error code is generated on the passed node |
1143 * See [_initialFieldElementsMap], | 1120 * See [_initialFieldElementsMap], |
(...skipping 23 matching lines...) Expand all Loading... |
1167 if (parameter is FieldFormalParameter) { | 1144 if (parameter is FieldFormalParameter) { |
1168 FieldElement fieldElement = | 1145 FieldElement fieldElement = |
1169 (parameter.element as FieldFormalParameterElementImpl).field; | 1146 (parameter.element as FieldFormalParameterElementImpl).field; |
1170 INIT_STATE state = fieldElementsMap[fieldElement]; | 1147 INIT_STATE state = fieldElementsMap[fieldElement]; |
1171 if (state == INIT_STATE.NOT_INIT) { | 1148 if (state == INIT_STATE.NOT_INIT) { |
1172 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL; | 1149 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL; |
1173 } else if (state == INIT_STATE.INIT_IN_DECLARATION) { | 1150 } else if (state == INIT_STATE.INIT_IN_DECLARATION) { |
1174 if (fieldElement.isFinal || fieldElement.isConst) { | 1151 if (fieldElement.isFinal || fieldElement.isConst) { |
1175 _errorReporter.reportErrorForNode( | 1152 _errorReporter.reportErrorForNode( |
1176 StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCT
OR, | 1153 StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCT
OR, |
1177 formalParameter.identifier, | 1154 formalParameter.identifier, [fieldElement.displayName]); |
1178 [fieldElement.displayName]); | |
1179 foundError = true; | 1155 foundError = true; |
1180 } | 1156 } |
1181 } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) { | 1157 } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) { |
1182 if (fieldElement.isFinal || fieldElement.isConst) { | 1158 if (fieldElement.isFinal || fieldElement.isConst) { |
1183 _errorReporter.reportErrorForNode( | 1159 _errorReporter.reportErrorForNode( |
1184 CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, | 1160 CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, |
1185 formalParameter.identifier, | 1161 formalParameter.identifier, [fieldElement.displayName]); |
1186 [fieldElement.displayName]); | |
1187 foundError = true; | 1162 foundError = true; |
1188 } | 1163 } |
1189 } | 1164 } |
1190 } | 1165 } |
1191 } | 1166 } |
1192 // Visit all of the initializers | 1167 // Visit all of the initializers |
1193 NodeList<ConstructorInitializer> initializers = node.initializers; | 1168 NodeList<ConstructorInitializer> initializers = node.initializers; |
1194 for (ConstructorInitializer constructorInitializer in initializers) { | 1169 for (ConstructorInitializer constructorInitializer in initializers) { |
1195 if (constructorInitializer is RedirectingConstructorInvocation) { | 1170 if (constructorInitializer is RedirectingConstructorInvocation) { |
1196 return false; | 1171 return false; |
(...skipping 16 matching lines...) Expand all Loading... |
1213 foundError = true; | 1188 foundError = true; |
1214 } | 1189 } |
1215 } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) { | 1190 } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) { |
1216 _errorReporter.reportErrorForNode( | 1191 _errorReporter.reportErrorForNode( |
1217 CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALI
ZER, | 1192 CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALI
ZER, |
1218 fieldName); | 1193 fieldName); |
1219 foundError = true; | 1194 foundError = true; |
1220 } else if (state == INIT_STATE.INIT_IN_INITIALIZERS) { | 1195 } else if (state == INIT_STATE.INIT_IN_INITIALIZERS) { |
1221 _errorReporter.reportErrorForNode( | 1196 _errorReporter.reportErrorForNode( |
1222 CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS, | 1197 CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS, |
1223 fieldName, | 1198 fieldName, [fieldElement.displayName]); |
1224 [fieldElement.displayName]); | |
1225 foundError = true; | 1199 foundError = true; |
1226 } | 1200 } |
1227 } | 1201 } |
1228 } | 1202 } |
1229 } | 1203 } |
1230 // Visit all of the states in the map to ensure that none were never | 1204 // Visit all of the states in the map to ensure that none were never |
1231 // initialized. | 1205 // initialized. |
1232 fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) { | 1206 fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) { |
1233 if (state == INIT_STATE.NOT_INIT) { | 1207 if (state == INIT_STATE.NOT_INIT) { |
1234 if (fieldElement.isConst) { | 1208 if (fieldElement.isConst) { |
1235 _errorReporter.reportErrorForNode( | 1209 _errorReporter.reportErrorForNode( |
1236 CompileTimeErrorCode.CONST_NOT_INITIALIZED, | 1210 CompileTimeErrorCode.CONST_NOT_INITIALIZED, node.returnType, [ |
1237 node.returnType, | 1211 fieldElement.name |
1238 [fieldElement.name]); | 1212 ]); |
1239 foundError = true; | 1213 foundError = true; |
1240 } else if (fieldElement.isFinal) { | 1214 } else if (fieldElement.isFinal) { |
1241 _errorReporter.reportErrorForNode( | 1215 _errorReporter.reportErrorForNode( |
1242 StaticWarningCode.FINAL_NOT_INITIALIZED, | 1216 StaticWarningCode.FINAL_NOT_INITIALIZED, node.returnType, [ |
1243 node.returnType, | 1217 fieldElement.name |
1244 [fieldElement.name]); | 1218 ]); |
1245 foundError = true; | 1219 foundError = true; |
1246 } | 1220 } |
1247 } | 1221 } |
1248 }); | 1222 }); |
1249 return foundError; | 1223 return foundError; |
1250 } | 1224 } |
1251 | 1225 |
1252 /** | 1226 /** |
1253 * This checks the passed executable element against override-error codes. | 1227 * This checks the passed executable element against override-error codes. |
1254 * | 1228 * |
1255 * @param executableElement a non-null [ExecutableElement] to evaluate | 1229 * @param executableElement a non-null [ExecutableElement] to evaluate |
1256 * @param overriddenExecutable the element that the executableElement is overr
iding | 1230 * @param overriddenExecutable the element that the executableElement is overr
iding |
1257 * @param parameters the parameters of the executable element | 1231 * @param parameters the parameters of the executable element |
1258 * @param errorNameTarget the node to report problems on | 1232 * @param errorNameTarget the node to report problems on |
1259 * @return `true` if and only if an error code is generated on the passed node | 1233 * @return `true` if and only if an error code is generated on the passed node |
1260 * See [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
], | 1234 * See [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
], |
1261 * [CompileTimeErrorCode.INVALID_OVERRIDE_REQUIRED], | 1235 * [CompileTimeErrorCode.INVALID_OVERRIDE_REQUIRED], |
1262 * [CompileTimeErrorCode.INVALID_OVERRIDE_POSITIONAL], | 1236 * [CompileTimeErrorCode.INVALID_OVERRIDE_POSITIONAL], |
1263 * [CompileTimeErrorCode.INVALID_OVERRIDE_NAMED], | 1237 * [CompileTimeErrorCode.INVALID_OVERRIDE_NAMED], |
1264 * [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE], | 1238 * [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE], |
1265 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE], | 1239 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE], |
1266 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE], | 1240 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE], |
1267 * [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE], | 1241 * [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE], |
1268 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE], | 1242 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE], |
1269 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE], and | 1243 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE], and |
1270 * [StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES]. | 1244 * [StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES]. |
1271 */ | 1245 */ |
1272 bool | 1246 bool _checkForAllInvalidOverrideErrorCodes( |
1273 _checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement, | 1247 ExecutableElement executableElement, |
1274 ExecutableElement overriddenExecutable, List<ParameterElement> parameters, | 1248 ExecutableElement overriddenExecutable, List<ParameterElement> parameters, |
1275 List<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) { | 1249 List<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) { |
1276 bool isGetter = false; | 1250 bool isGetter = false; |
1277 bool isSetter = false; | 1251 bool isSetter = false; |
1278 if (executableElement is PropertyAccessorElement) { | 1252 if (executableElement is PropertyAccessorElement) { |
1279 PropertyAccessorElement accessorElement = executableElement; | 1253 PropertyAccessorElement accessorElement = executableElement; |
1280 isGetter = accessorElement.isGetter; | 1254 isGetter = accessorElement.isGetter; |
1281 isSetter = accessorElement.isSetter; | 1255 isSetter = accessorElement.isSetter; |
1282 } | 1256 } |
1283 String executableElementName = executableElement.name; | 1257 String executableElementName = executableElement.name; |
1284 FunctionType overridingFT = executableElement.type; | 1258 FunctionType overridingFT = executableElement.type; |
1285 FunctionType overriddenFT = overriddenExecutable.type; | 1259 FunctionType overriddenFT = overriddenExecutable.type; |
1286 InterfaceType enclosingType = _enclosingClass.type; | 1260 InterfaceType enclosingType = _enclosingClass.type; |
1287 overriddenFT = | 1261 overriddenFT = _inheritanceManager |
1288 _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance( | 1262 .substituteTypeArgumentsInMemberFromInheritance( |
1289 overriddenFT, | 1263 overriddenFT, executableElementName, enclosingType); |
1290 executableElementName, | |
1291 enclosingType); | |
1292 if (overridingFT == null || overriddenFT == null) { | 1264 if (overridingFT == null || overriddenFT == null) { |
1293 return false; | 1265 return false; |
1294 } | 1266 } |
1295 DartType overridingFTReturnType = overridingFT.returnType; | 1267 DartType overridingFTReturnType = overridingFT.returnType; |
1296 DartType overriddenFTReturnType = overriddenFT.returnType; | 1268 DartType overriddenFTReturnType = overriddenFT.returnType; |
1297 List<DartType> overridingNormalPT = overridingFT.normalParameterTypes; | 1269 List<DartType> overridingNormalPT = overridingFT.normalParameterTypes; |
1298 List<DartType> overriddenNormalPT = overriddenFT.normalParameterTypes; | 1270 List<DartType> overriddenNormalPT = overriddenFT.normalParameterTypes; |
1299 List<DartType> overridingPositionalPT = overridingFT.optionalParameterTypes; | 1271 List<DartType> overridingPositionalPT = overridingFT.optionalParameterTypes; |
1300 List<DartType> overriddenPositionalPT = overriddenFT.optionalParameterTypes; | 1272 List<DartType> overriddenPositionalPT = overriddenFT.optionalParameterTypes; |
1301 Map<String, DartType> overridingNamedPT = overridingFT.namedParameterTypes; | 1273 Map<String, DartType> overridingNamedPT = overridingFT.namedParameterTypes; |
1302 Map<String, DartType> overriddenNamedPT = overriddenFT.namedParameterTypes; | 1274 Map<String, DartType> overriddenNamedPT = overriddenFT.namedParameterTypes; |
1303 // CTEC.INVALID_OVERRIDE_REQUIRED, CTEC.INVALID_OVERRIDE_POSITIONAL and | 1275 // CTEC.INVALID_OVERRIDE_REQUIRED, CTEC.INVALID_OVERRIDE_POSITIONAL and |
1304 // CTEC.INVALID_OVERRIDE_NAMED | 1276 // CTEC.INVALID_OVERRIDE_NAMED |
1305 if (overridingNormalPT.length > overriddenNormalPT.length) { | 1277 if (overridingNormalPT.length > overriddenNormalPT.length) { |
1306 _errorReporter.reportErrorForNode( | 1278 _errorReporter.reportErrorForNode( |
1307 StaticWarningCode.INVALID_OVERRIDE_REQUIRED, | 1279 StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [ |
1308 errorNameTarget, | 1280 overriddenNormalPT.length, |
1309 [overriddenNormalPT.length, overriddenExecutable.enclosingElement.disp
layName]); | 1281 overriddenExecutable.enclosingElement.displayName |
| 1282 ]); |
1310 return true; | 1283 return true; |
1311 } | 1284 } |
1312 if (overridingNormalPT.length + overridingPositionalPT.length < | 1285 if (overridingNormalPT.length + overridingPositionalPT.length < |
1313 overriddenPositionalPT.length + overriddenNormalPT.length) { | 1286 overriddenPositionalPT.length + overriddenNormalPT.length) { |
1314 _errorReporter.reportErrorForNode( | 1287 _errorReporter.reportErrorForNode( |
1315 StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, | 1288 StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [ |
1316 errorNameTarget, | 1289 overriddenPositionalPT.length + overriddenNormalPT.length, |
1317 [ | 1290 overriddenExecutable.enclosingElement.displayName |
1318 overriddenPositionalPT.length + overriddenNormalPT.length, | 1291 ]); |
1319 overriddenExecutable.enclosingElement.displayName]); | |
1320 return true; | 1292 return true; |
1321 } | 1293 } |
1322 // For each named parameter in the overridden method, verify that there is | 1294 // For each named parameter in the overridden method, verify that there is |
1323 // the same name in the overriding method. | 1295 // the same name in the overriding method. |
1324 for (String overriddenParamName in overriddenNamedPT.keys) { | 1296 for (String overriddenParamName in overriddenNamedPT.keys) { |
1325 if (!overridingNamedPT.containsKey(overriddenParamName)) { | 1297 if (!overridingNamedPT.containsKey(overriddenParamName)) { |
1326 // The overridden method expected the overriding method to have | 1298 // The overridden method expected the overriding method to have |
1327 // overridingParamName, but it does not. | 1299 // overridingParamName, but it does not. |
1328 _errorReporter.reportErrorForNode( | 1300 _errorReporter.reportErrorForNode( |
1329 StaticWarningCode.INVALID_OVERRIDE_NAMED, | 1301 StaticWarningCode.INVALID_OVERRIDE_NAMED, errorNameTarget, [ |
1330 errorNameTarget, | 1302 overriddenParamName, |
1331 [overriddenParamName, overriddenExecutable.enclosingElement.displayN
ame]); | 1303 overriddenExecutable.enclosingElement.displayName |
| 1304 ]); |
1332 return true; | 1305 return true; |
1333 } | 1306 } |
1334 } | 1307 } |
1335 // SWC.INVALID_METHOD_OVERRIDE_RETURN_TYPE | 1308 // SWC.INVALID_METHOD_OVERRIDE_RETURN_TYPE |
1336 if (overriddenFTReturnType != VoidTypeImpl.instance && | 1309 if (overriddenFTReturnType != VoidTypeImpl.instance && |
1337 !overridingFTReturnType.isAssignableTo(overriddenFTReturnType)) { | 1310 !overridingFTReturnType.isAssignableTo(overriddenFTReturnType)) { |
1338 _errorReporter.reportTypeErrorForNode( | 1311 _errorReporter.reportTypeErrorForNode(!isGetter |
1339 !isGetter ? | 1312 ? StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE |
1340 StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE : | 1313 : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, |
1341 StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, | 1314 errorNameTarget, [ |
1342 errorNameTarget, | 1315 overridingFTReturnType, |
1343 [ | 1316 overriddenFTReturnType, |
1344 overridingFTReturnType, | 1317 overriddenExecutable.enclosingElement.displayName |
1345 overriddenFTReturnType, | 1318 ]); |
1346 overriddenExecutable.enclosingElement.displayName]); | |
1347 return true; | 1319 return true; |
1348 } | 1320 } |
1349 // SWC.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE | 1321 // SWC.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE |
1350 if (parameterLocations == null) { | 1322 if (parameterLocations == null) { |
1351 return false; | 1323 return false; |
1352 } | 1324 } |
1353 int parameterIndex = 0; | 1325 int parameterIndex = 0; |
1354 for (int i = 0; i < overridingNormalPT.length; i++) { | 1326 for (int i = 0; i < overridingNormalPT.length; i++) { |
1355 if (!overridingNormalPT[i].isAssignableTo(overriddenNormalPT[i])) { | 1327 if (!overridingNormalPT[i].isAssignableTo(overriddenNormalPT[i])) { |
1356 _errorReporter.reportTypeErrorForNode( | 1328 _errorReporter.reportTypeErrorForNode(!isSetter |
1357 !isSetter ? | 1329 ? StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE |
1358 StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE : | 1330 : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE, |
1359 StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE, | 1331 parameterLocations[parameterIndex], [ |
1360 parameterLocations[parameterIndex], | 1332 overridingNormalPT[i], |
1361 [ | 1333 overriddenNormalPT[i], |
1362 overridingNormalPT[i], | 1334 overriddenExecutable.enclosingElement.displayName |
1363 overriddenNormalPT[i], | 1335 ]); |
1364 overriddenExecutable.enclosingElement.displayName]); | |
1365 return true; | 1336 return true; |
1366 } | 1337 } |
1367 parameterIndex++; | 1338 parameterIndex++; |
1368 } | 1339 } |
1369 // SWC.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE | 1340 // SWC.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE |
1370 for (int i = 0; i < overriddenPositionalPT.length; i++) { | 1341 for (int i = 0; i < overriddenPositionalPT.length; i++) { |
1371 if (!overridingPositionalPT[i].isAssignableTo( | 1342 if (!overridingPositionalPT[i] |
1372 overriddenPositionalPT[i])) { | 1343 .isAssignableTo(overriddenPositionalPT[i])) { |
1373 _errorReporter.reportTypeErrorForNode( | 1344 _errorReporter.reportTypeErrorForNode( |
1374 StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE, | 1345 StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE, |
1375 parameterLocations[parameterIndex], | 1346 parameterLocations[parameterIndex], [ |
1376 [ | 1347 overridingPositionalPT[i], |
1377 overridingPositionalPT[i], | 1348 overriddenPositionalPT[i], |
1378 overriddenPositionalPT[i], | 1349 overriddenExecutable.enclosingElement.displayName |
1379 overriddenExecutable.enclosingElement.displayName]); | 1350 ]); |
1380 return true; | 1351 return true; |
1381 } | 1352 } |
1382 parameterIndex++; | 1353 parameterIndex++; |
1383 } | 1354 } |
1384 // SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE & | 1355 // SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE & |
1385 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES | 1356 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES |
1386 for (String overriddenName in overriddenNamedPT.keys) { | 1357 for (String overriddenName in overriddenNamedPT.keys) { |
1387 DartType overridingType = overridingNamedPT[overriddenName]; | 1358 DartType overridingType = overridingNamedPT[overriddenName]; |
1388 if (overridingType == null) { | 1359 if (overridingType == null) { |
1389 // Error, this is never reached- INVALID_OVERRIDE_NAMED would have been | 1360 // Error, this is never reached- INVALID_OVERRIDE_NAMED would have been |
(...skipping 10 matching lines...) Expand all Loading... |
1400 if (parameter.parameterKind == ParameterKind.NAMED && | 1371 if (parameter.parameterKind == ParameterKind.NAMED && |
1401 overriddenName == parameter.name) { | 1372 overriddenName == parameter.name) { |
1402 parameterToSelect = parameter; | 1373 parameterToSelect = parameter; |
1403 parameterLocationToSelect = parameterLocations[i]; | 1374 parameterLocationToSelect = parameterLocations[i]; |
1404 break; | 1375 break; |
1405 } | 1376 } |
1406 } | 1377 } |
1407 if (parameterToSelect != null) { | 1378 if (parameterToSelect != null) { |
1408 _errorReporter.reportTypeErrorForNode( | 1379 _errorReporter.reportTypeErrorForNode( |
1409 StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE, | 1380 StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE, |
1410 parameterLocationToSelect, | 1381 parameterLocationToSelect, [ |
1411 [ | 1382 overridingType, |
1412 overridingType, | 1383 overriddenType, |
1413 overriddenType, | 1384 overriddenExecutable.enclosingElement.displayName |
1414 overriddenExecutable.enclosingElement.displayName]); | 1385 ]); |
1415 return true; | 1386 return true; |
1416 } | 1387 } |
1417 } | 1388 } |
1418 } | 1389 } |
1419 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES | 1390 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES |
1420 // | 1391 // |
1421 // Create three arrays: an array of the optional parameter ASTs | 1392 // Create three arrays: an array of the optional parameter ASTs |
1422 // (FormalParameters), an array of the optional parameters elements from our | 1393 // (FormalParameters), an array of the optional parameters elements from our |
1423 // method, and finally an array of the optional parameter elements from the | 1394 // method, and finally an array of the optional parameter elements from the |
1424 // method we are overriding. | 1395 // method we are overriding. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1471 if (parameterName != null && | 1442 if (parameterName != null && |
1472 parameterName == overriddenParameterName) { | 1443 parameterName == overriddenParameterName) { |
1473 EvaluationResultImpl overriddenResult = | 1444 EvaluationResultImpl overriddenResult = |
1474 overriddenParameterElt.evaluationResult; | 1445 overriddenParameterElt.evaluationResult; |
1475 if (_isUserDefinedObject(overriddenResult)) { | 1446 if (_isUserDefinedObject(overriddenResult)) { |
1476 break; | 1447 break; |
1477 } | 1448 } |
1478 if (!result.equalValues(_typeProvider, overriddenResult)) { | 1449 if (!result.equalValues(_typeProvider, overriddenResult)) { |
1479 _errorReporter.reportErrorForNode( | 1450 _errorReporter.reportErrorForNode( |
1480 StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_
NAMED, | 1451 StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_
NAMED, |
1481 formalParameters[i], | 1452 formalParameters[i], [ |
1482 [ | 1453 overriddenExecutable.enclosingElement.displayName, |
1483 overriddenExecutable.enclosingElement.displayName, | 1454 overriddenExecutable.displayName, |
1484 overriddenExecutable.displayName, | 1455 parameterName |
1485 parameterName]); | 1456 ]); |
1486 foundError = true; | 1457 foundError = true; |
1487 } | 1458 } |
1488 } | 1459 } |
1489 } | 1460 } |
1490 } | 1461 } |
1491 } else { | 1462 } else { |
1492 // Positional parameters, consider the positions when matching the | 1463 // Positional parameters, consider the positions when matching the |
1493 // parameterElts to the overriddenParameterElts | 1464 // parameterElts to the overriddenParameterElts |
1494 for (int i = | 1465 for (int i = 0; |
1495 0; i < parameterElts.length && i < overriddenParameterElts.length; i
++) { | 1466 i < parameterElts.length && i < overriddenParameterElts.length; |
| 1467 i++) { |
1496 ParameterElementImpl parameterElt = parameterElts[i]; | 1468 ParameterElementImpl parameterElt = parameterElts[i]; |
1497 EvaluationResultImpl result = parameterElt.evaluationResult; | 1469 EvaluationResultImpl result = parameterElt.evaluationResult; |
1498 // TODO (jwren) Ignore Object types, see Dart bug 11287 | 1470 // TODO (jwren) Ignore Object types, see Dart bug 11287 |
1499 if (_isUserDefinedObject(result)) { | 1471 if (_isUserDefinedObject(result)) { |
1500 continue; | 1472 continue; |
1501 } | 1473 } |
1502 ParameterElementImpl overriddenParameterElt = | 1474 ParameterElementImpl overriddenParameterElt = |
1503 overriddenParameterElts[i]; | 1475 overriddenParameterElts[i]; |
1504 if (overriddenParameterElt.initializer == null) { | 1476 if (overriddenParameterElt.initializer == null) { |
1505 // There is no warning if the overridden parameter has an implicit | 1477 // There is no warning if the overridden parameter has an implicit |
1506 // default. | 1478 // default. |
1507 continue; | 1479 continue; |
1508 } | 1480 } |
1509 EvaluationResultImpl overriddenResult = | 1481 EvaluationResultImpl overriddenResult = |
1510 overriddenParameterElt.evaluationResult; | 1482 overriddenParameterElt.evaluationResult; |
1511 if (_isUserDefinedObject(overriddenResult)) { | 1483 if (_isUserDefinedObject(overriddenResult)) { |
1512 continue; | 1484 continue; |
1513 } | 1485 } |
1514 if (!result.equalValues(_typeProvider, overriddenResult)) { | 1486 if (!result.equalValues(_typeProvider, overriddenResult)) { |
1515 _errorReporter.reportErrorForNode( | 1487 _errorReporter.reportErrorForNode( |
1516 StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSI
TIONAL, | 1488 StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSI
TIONAL, |
1517 formalParameters[i], | 1489 formalParameters[i], [ |
1518 [ | 1490 overriddenExecutable.enclosingElement.displayName, |
1519 overriddenExecutable.enclosingElement.displayName, | 1491 overriddenExecutable.displayName |
1520 overriddenExecutable.displayName]); | 1492 ]); |
1521 foundError = true; | 1493 foundError = true; |
1522 } | 1494 } |
1523 } | 1495 } |
1524 } | 1496 } |
1525 } | 1497 } |
1526 return foundError; | 1498 return foundError; |
1527 } | 1499 } |
1528 | 1500 |
1529 /** | 1501 /** |
1530 * This checks the passed executable element against override-error codes. Thi
s method computes | 1502 * This checks the passed executable element against override-error codes. Thi
s method computes |
1531 * the passed executableElement is overriding and calls | 1503 * the passed executableElement is overriding and calls |
1532 * [checkForAllInvalidOverrideErrorCodes] | 1504 * [checkForAllInvalidOverrideErrorCodes] |
1533 * when the [InheritanceManager] returns a [MultiplyInheritedExecutableElement
], this | 1505 * when the [InheritanceManager] returns a [MultiplyInheritedExecutableElement
], this |
1534 * method loops through the array in the [MultiplyInheritedExecutableElement]. | 1506 * method loops through the array in the [MultiplyInheritedExecutableElement]. |
1535 * | 1507 * |
1536 * @param executableElement a non-null [ExecutableElement] to evaluate | 1508 * @param executableElement a non-null [ExecutableElement] to evaluate |
1537 * @param parameters the parameters of the executable element | 1509 * @param parameters the parameters of the executable element |
1538 * @param errorNameTarget the node to report problems on | 1510 * @param errorNameTarget the node to report problems on |
1539 * @return `true` if and only if an error code is generated on the passed node | 1511 * @return `true` if and only if an error code is generated on the passed node |
1540 */ | 1512 */ |
1541 bool | 1513 bool _checkForAllInvalidOverrideErrorCodesForExecutable( |
1542 _checkForAllInvalidOverrideErrorCodesForExecutable(ExecutableElement execu
tableElement, | 1514 ExecutableElement executableElement, List<ParameterElement> parameters, |
1543 List<ParameterElement> parameters, List<AstNode> parameterLocations, | 1515 List<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) { |
1544 SimpleIdentifier errorNameTarget) { | |
1545 // | 1516 // |
1546 // Compute the overridden executable from the InheritanceManager | 1517 // Compute the overridden executable from the InheritanceManager |
1547 // | 1518 // |
1548 List<ExecutableElement> overriddenExecutables = | 1519 List<ExecutableElement> overriddenExecutables = _inheritanceManager |
1549 _inheritanceManager.lookupOverrides(_enclosingClass, executableElement.n
ame); | 1520 .lookupOverrides(_enclosingClass, executableElement.name); |
1550 if (_checkForInstanceMethodNameCollidesWithSuperclassStatic( | 1521 if (_checkForInstanceMethodNameCollidesWithSuperclassStatic( |
1551 executableElement, | 1522 executableElement, errorNameTarget)) { |
1552 errorNameTarget)) { | |
1553 return true; | 1523 return true; |
1554 } | 1524 } |
1555 for (ExecutableElement overriddenElement in overriddenExecutables) { | 1525 for (ExecutableElement overriddenElement in overriddenExecutables) { |
1556 if (_checkForAllInvalidOverrideErrorCodes( | 1526 if (_checkForAllInvalidOverrideErrorCodes(executableElement, |
1557 executableElement, | 1527 overriddenElement, parameters, parameterLocations, errorNameTarget)) { |
1558 overriddenElement, | |
1559 parameters, | |
1560 parameterLocations, | |
1561 errorNameTarget)) { | |
1562 return true; | 1528 return true; |
1563 } | 1529 } |
1564 } | 1530 } |
1565 return false; | 1531 return false; |
1566 } | 1532 } |
1567 | 1533 |
1568 /** | 1534 /** |
1569 * This checks the passed field declaration against override-error codes. | 1535 * This checks the passed field declaration against override-error codes. |
1570 * | 1536 * |
1571 * @param node the [MethodDeclaration] to evaluate | 1537 * @param node the [MethodDeclaration] to evaluate |
1572 * @return `true` if and only if an error code is generated on the passed node | 1538 * @return `true` if and only if an error code is generated on the passed node |
1573 * See [_checkForAllInvalidOverrideErrorCodes]. | 1539 * See [_checkForAllInvalidOverrideErrorCodes]. |
1574 */ | 1540 */ |
1575 bool _checkForAllInvalidOverrideErrorCodesForField(FieldDeclaration node) { | 1541 bool _checkForAllInvalidOverrideErrorCodesForField(FieldDeclaration node) { |
1576 if (_enclosingClass == null || node.isStatic) { | 1542 if (_enclosingClass == null || node.isStatic) { |
1577 return false; | 1543 return false; |
1578 } | 1544 } |
1579 bool hasProblems = false; | 1545 bool hasProblems = false; |
1580 VariableDeclarationList fields = node.fields; | 1546 VariableDeclarationList fields = node.fields; |
1581 for (VariableDeclaration field in fields.variables) { | 1547 for (VariableDeclaration field in fields.variables) { |
1582 FieldElement element = field.element as FieldElement; | 1548 FieldElement element = field.element as FieldElement; |
1583 if (element == null) { | 1549 if (element == null) { |
1584 continue; | 1550 continue; |
1585 } | 1551 } |
1586 PropertyAccessorElement getter = element.getter; | 1552 PropertyAccessorElement getter = element.getter; |
1587 PropertyAccessorElement setter = element.setter; | 1553 PropertyAccessorElement setter = element.setter; |
1588 SimpleIdentifier fieldName = field.name; | 1554 SimpleIdentifier fieldName = field.name; |
1589 if (getter != null) { | 1555 if (getter != null) { |
1590 if (_checkForAllInvalidOverrideErrorCodesForExecutable( | 1556 if (_checkForAllInvalidOverrideErrorCodesForExecutable(getter, |
1591 getter, | 1557 ParameterElementImpl.EMPTY_ARRAY, AstNode.EMPTY_LIST, fieldName)) { |
1592 ParameterElementImpl.EMPTY_ARRAY, | |
1593 AstNode.EMPTY_LIST, | |
1594 fieldName)) { | |
1595 hasProblems = true; | 1558 hasProblems = true; |
1596 } | 1559 } |
1597 } | 1560 } |
1598 if (setter != null) { | 1561 if (setter != null) { |
1599 if (_checkForAllInvalidOverrideErrorCodesForExecutable( | 1562 if (_checkForAllInvalidOverrideErrorCodesForExecutable( |
1600 setter, | 1563 setter, setter.parameters, <AstNode>[fieldName], fieldName)) { |
1601 setter.parameters, | |
1602 <AstNode>[fieldName], | |
1603 fieldName)) { | |
1604 hasProblems = true; | 1564 hasProblems = true; |
1605 } | 1565 } |
1606 } | 1566 } |
1607 } | 1567 } |
1608 return hasProblems; | 1568 return hasProblems; |
1609 } | 1569 } |
1610 | 1570 |
1611 /** | 1571 /** |
1612 * This checks the passed method declaration against override-error codes. | 1572 * This checks the passed method declaration against override-error codes. |
1613 * | 1573 * |
(...skipping 13 matching lines...) Expand all Loading... |
1627 } | 1587 } |
1628 SimpleIdentifier methodName = node.name; | 1588 SimpleIdentifier methodName = node.name; |
1629 if (methodName.isSynthetic) { | 1589 if (methodName.isSynthetic) { |
1630 return false; | 1590 return false; |
1631 } | 1591 } |
1632 FormalParameterList formalParameterList = node.parameters; | 1592 FormalParameterList formalParameterList = node.parameters; |
1633 NodeList<FormalParameter> parameterList = | 1593 NodeList<FormalParameter> parameterList = |
1634 formalParameterList != null ? formalParameterList.parameters : null; | 1594 formalParameterList != null ? formalParameterList.parameters : null; |
1635 List<AstNode> parameters = | 1595 List<AstNode> parameters = |
1636 parameterList != null ? new List.from(parameterList) : null; | 1596 parameterList != null ? new List.from(parameterList) : null; |
1637 return _checkForAllInvalidOverrideErrorCodesForExecutable( | 1597 return _checkForAllInvalidOverrideErrorCodesForExecutable(executableElement, |
1638 executableElement, | 1598 executableElement.parameters, parameters, methodName); |
1639 executableElement.parameters, | |
1640 parameters, | |
1641 methodName); | |
1642 } | 1599 } |
1643 | 1600 |
1644 /** | 1601 /** |
1645 * This verifies that all classes of the passed 'with' clause are valid. | 1602 * This verifies that all classes of the passed 'with' clause are valid. |
1646 * | 1603 * |
1647 * @param node the 'with' clause to evaluate | 1604 * @param node the 'with' clause to evaluate |
1648 * @return `true` if and only if an error code is generated on the passed node | 1605 * @return `true` if and only if an error code is generated on the passed node |
1649 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR], | 1606 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR], |
1650 * [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT], and | 1607 * [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT], and |
1651 * [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]. | 1608 * [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]. |
1652 */ | 1609 */ |
1653 bool _checkForAllMixinErrorCodes(WithClause withClause) { | 1610 bool _checkForAllMixinErrorCodes(WithClause withClause) { |
1654 if (withClause == null) { | 1611 if (withClause == null) { |
1655 return false; | 1612 return false; |
1656 } | 1613 } |
1657 bool problemReported = false; | 1614 bool problemReported = false; |
1658 for (TypeName mixinName in withClause.mixinTypes) { | 1615 for (TypeName mixinName in withClause.mixinTypes) { |
1659 DartType mixinType = mixinName.type; | 1616 DartType mixinType = mixinName.type; |
1660 if (mixinType is! InterfaceType) { | 1617 if (mixinType is! InterfaceType) { |
1661 continue; | 1618 continue; |
1662 } | 1619 } |
1663 if (_checkForExtendsOrImplementsDisallowedClass( | 1620 if (_checkForExtendsOrImplementsDisallowedClass( |
1664 mixinName, | 1621 mixinName, CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS)) { |
1665 CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS)) { | |
1666 problemReported = true; | 1622 problemReported = true; |
1667 } else { | 1623 } else { |
1668 ClassElement mixinElement = (mixinType as InterfaceType).element; | 1624 ClassElement mixinElement = (mixinType as InterfaceType).element; |
1669 if (_checkForExtendsOrImplementsDeferredClass( | 1625 if (_checkForExtendsOrImplementsDeferredClass( |
1670 mixinName, | 1626 mixinName, CompileTimeErrorCode.MIXIN_DEFERRED_CLASS)) { |
1671 CompileTimeErrorCode.MIXIN_DEFERRED_CLASS)) { | |
1672 problemReported = true; | 1627 problemReported = true; |
1673 } | 1628 } |
1674 if (_checkForMixinDeclaresConstructor(mixinName, mixinElement)) { | 1629 if (_checkForMixinDeclaresConstructor(mixinName, mixinElement)) { |
1675 problemReported = true; | 1630 problemReported = true; |
1676 } | 1631 } |
1677 if (_checkForMixinInheritsNotFromObject(mixinName, mixinElement)) { | 1632 if (_checkForMixinInheritsNotFromObject(mixinName, mixinElement)) { |
1678 problemReported = true; | 1633 problemReported = true; |
1679 } | 1634 } |
1680 if (_checkForMixinReferencesSuper(mixinName, mixinElement)) { | 1635 if (_checkForMixinReferencesSuper(mixinName, mixinElement)) { |
1681 problemReported = true; | 1636 problemReported = true; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1716 if (redirectedType != null && | 1671 if (redirectedType != null && |
1717 redirectedType.element != null && | 1672 redirectedType.element != null && |
1718 !redirectedType.isDynamic) { | 1673 !redirectedType.isDynamic) { |
1719 // | 1674 // |
1720 // Prepare the constructor name | 1675 // Prepare the constructor name |
1721 // | 1676 // |
1722 String constructorStrName = constructorTypeName.name.name; | 1677 String constructorStrName = constructorTypeName.name.name; |
1723 if (redirectedConstructor.name != null) { | 1678 if (redirectedConstructor.name != null) { |
1724 constructorStrName += ".${redirectedConstructor.name.name}"; | 1679 constructorStrName += ".${redirectedConstructor.name.name}"; |
1725 } | 1680 } |
1726 ErrorCode errorCode = (node.constKeyword != null ? | 1681 ErrorCode errorCode = (node.constKeyword != null |
1727 CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR : | 1682 ? CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR |
1728 StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR); | 1683 : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR); |
1729 _errorReporter.reportErrorForNode( | 1684 _errorReporter.reportErrorForNode(errorCode, redirectedConstructor, |
1730 errorCode, | |
1731 redirectedConstructor, | |
1732 [constructorStrName, redirectedType.displayName]); | 1685 [constructorStrName, redirectedType.displayName]); |
1733 return true; | 1686 return true; |
1734 } | 1687 } |
1735 return false; | 1688 return false; |
1736 } | 1689 } |
1737 FunctionType redirectedType = redirectedElement.type; | 1690 FunctionType redirectedType = redirectedElement.type; |
1738 DartType redirectedReturnType = redirectedType.returnType; | 1691 DartType redirectedReturnType = redirectedType.returnType; |
1739 // | 1692 // |
1740 // Report specific problem when return type is incompatible | 1693 // Report specific problem when return type is incompatible |
1741 // | 1694 // |
1742 FunctionType constructorType = node.element.type; | 1695 FunctionType constructorType = node.element.type; |
1743 DartType constructorReturnType = constructorType.returnType; | 1696 DartType constructorReturnType = constructorType.returnType; |
1744 if (!redirectedReturnType.isAssignableTo(constructorReturnType)) { | 1697 if (!redirectedReturnType.isAssignableTo(constructorReturnType)) { |
1745 _errorReporter.reportErrorForNode( | 1698 _errorReporter.reportErrorForNode( |
1746 StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, | 1699 StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, |
1747 redirectedConstructor, | 1700 redirectedConstructor, [redirectedReturnType, constructorReturnType]); |
1748 [redirectedReturnType, constructorReturnType]); | |
1749 return true; | 1701 return true; |
1750 } | 1702 } |
1751 // | 1703 // |
1752 // Check parameters | 1704 // Check parameters |
1753 // | 1705 // |
1754 if (!redirectedType.isSubtypeOf(constructorType)) { | 1706 if (!redirectedType.isSubtypeOf(constructorType)) { |
1755 _errorReporter.reportErrorForNode( | 1707 _errorReporter.reportErrorForNode( |
1756 StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE, | 1708 StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE, |
1757 redirectedConstructor, | 1709 redirectedConstructor, [redirectedType, constructorType]); |
1758 [redirectedType, constructorType]); | |
1759 return true; | 1710 return true; |
1760 } | 1711 } |
1761 return false; | 1712 return false; |
1762 } | 1713 } |
1763 | 1714 |
1764 /** | 1715 /** |
1765 * This checks that the return statement of the form <i>return e;</i> is not i
n a generative | 1716 * This checks that the return statement of the form <i>return e;</i> is not i
n a generative |
1766 * constructor. | 1717 * constructor. |
1767 * | 1718 * |
1768 * This checks that return statements without expressions are not in a generat
ive constructor and | 1719 * This checks that return statements without expressions are not in a generat
ive constructor and |
1769 * the return type is not assignable to `null`; that is, we don't have `return
;` if | 1720 * the return type is not assignable to `null`; that is, we don't have `return
;` if |
1770 * the enclosing method has a return type. | 1721 * the enclosing method has a return type. |
1771 * | 1722 * |
1772 * This checks that the return type matches the type of the declared return ty
pe in the enclosing | 1723 * This checks that the return type matches the type of the declared return ty
pe in the enclosing |
1773 * method or function. | 1724 * method or function. |
1774 * | 1725 * |
1775 * @param node the return statement to evaluate | 1726 * @param node the return statement to evaluate |
1776 * @return `true` if and only if an error code is generated on the passed node | 1727 * @return `true` if and only if an error code is generated on the passed node |
1777 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR], | 1728 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR], |
1778 * [StaticWarningCode.RETURN_WITHOUT_VALUE], and | 1729 * [StaticWarningCode.RETURN_WITHOUT_VALUE], and |
1779 * [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. | 1730 * [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. |
1780 */ | 1731 */ |
1781 bool _checkForAllReturnStatementErrorCodes(ReturnStatement node) { | 1732 bool _checkForAllReturnStatementErrorCodes(ReturnStatement node) { |
1782 FunctionType functionType = | 1733 FunctionType functionType = |
1783 _enclosingFunction == null ? null : _enclosingFunction.type; | 1734 _enclosingFunction == null ? null : _enclosingFunction.type; |
1784 DartType expectedReturnType = | 1735 DartType expectedReturnType = functionType == null |
1785 functionType == null ? DynamicTypeImpl.instance : functionType.returnTyp
e; | 1736 ? DynamicTypeImpl.instance |
| 1737 : functionType.returnType; |
1786 Expression returnExpression = node.expression; | 1738 Expression returnExpression = node.expression; |
1787 // RETURN_IN_GENERATIVE_CONSTRUCTOR | 1739 // RETURN_IN_GENERATIVE_CONSTRUCTOR |
1788 bool isGenerativeConstructor = | 1740 bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && |
1789 _enclosingFunction is ConstructorElement && | |
1790 !(_enclosingFunction as ConstructorElement).isFactory; | 1741 !(_enclosingFunction as ConstructorElement).isFactory; |
1791 if (isGenerativeConstructor) { | 1742 if (isGenerativeConstructor) { |
1792 if (returnExpression == null) { | 1743 if (returnExpression == null) { |
1793 return false; | 1744 return false; |
1794 } | 1745 } |
1795 _errorReporter.reportErrorForNode( | 1746 _errorReporter.reportErrorForNode( |
1796 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, | 1747 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, |
1797 returnExpression); | 1748 returnExpression); |
1798 return true; | 1749 return true; |
1799 } | 1750 } |
1800 // RETURN_WITHOUT_VALUE | 1751 // RETURN_WITHOUT_VALUE |
1801 if (returnExpression == null) { | 1752 if (returnExpression == null) { |
1802 if (_inGenerator || | 1753 if (_inGenerator || |
1803 _computeReturnTypeForMethod(null).isAssignableTo(expectedReturnType))
{ | 1754 _computeReturnTypeForMethod(null) |
| 1755 .isAssignableTo(expectedReturnType)) { |
1804 return false; | 1756 return false; |
1805 } | 1757 } |
1806 _hasReturnWithoutValue = true; | 1758 _hasReturnWithoutValue = true; |
1807 _errorReporter.reportErrorForNode( | 1759 _errorReporter |
1808 StaticWarningCode.RETURN_WITHOUT_VALUE, | 1760 .reportErrorForNode(StaticWarningCode.RETURN_WITHOUT_VALUE, node); |
1809 node); | |
1810 return true; | 1761 return true; |
1811 } else if (_inGenerator) { | 1762 } else if (_inGenerator) { |
1812 // RETURN_IN_GENERATOR | 1763 // RETURN_IN_GENERATOR |
1813 _errorReporter.reportErrorForNode( | 1764 _errorReporter |
1814 CompileTimeErrorCode.RETURN_IN_GENERATOR, | 1765 .reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATOR, node); |
1815 node); | |
1816 } | 1766 } |
1817 // RETURN_OF_INVALID_TYPE | 1767 // RETURN_OF_INVALID_TYPE |
1818 return _checkForReturnOfInvalidType(returnExpression, expectedReturnType); | 1768 return _checkForReturnOfInvalidType(returnExpression, expectedReturnType); |
1819 } | 1769 } |
1820 | 1770 |
1821 /** | 1771 /** |
1822 * This verifies that the export namespace of the passed export directive does
not export any name | 1772 * This verifies that the export namespace of the passed export directive does
not export any name |
1823 * already exported by other export directive. | 1773 * already exported by other export directive. |
1824 * | 1774 * |
1825 * @param node the export directive node to report problem on | 1775 * @param node the export directive node to report problem on |
1826 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the | 1776 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the |
1827 * node was `null`, then this method is not called | 1777 * node was `null`, then this method is not called |
1828 * @param exportedLibrary the library element containing the exported element | 1778 * @param exportedLibrary the library element containing the exported element |
1829 * @return `true` if and only if an error code is generated on the passed node | 1779 * @return `true` if and only if an error code is generated on the passed node |
1830 * See [CompileTimeErrorCode.AMBIGUOUS_EXPORT]. | 1780 * See [CompileTimeErrorCode.AMBIGUOUS_EXPORT]. |
1831 */ | 1781 */ |
1832 bool _checkForAmbiguousExport(ExportDirective node, | 1782 bool _checkForAmbiguousExport(ExportDirective node, |
1833 ExportElement exportElement, LibraryElement exportedLibrary) { | 1783 ExportElement exportElement, LibraryElement exportedLibrary) { |
1834 if (exportedLibrary == null) { | 1784 if (exportedLibrary == null) { |
1835 return false; | 1785 return false; |
1836 } | 1786 } |
1837 // check exported names | 1787 // check exported names |
1838 Namespace namespace = | 1788 Namespace namespace = |
1839 new NamespaceBuilder().createExportNamespaceForDirective(exportElement); | 1789 new NamespaceBuilder().createExportNamespaceForDirective(exportElement); |
1840 Map<String, Element> definedNames = namespace.definedNames; | 1790 Map<String, Element> definedNames = namespace.definedNames; |
1841 for (String name in definedNames.keys) { | 1791 for (String name in definedNames.keys) { |
1842 Element element = definedNames[name]; | 1792 Element element = definedNames[name]; |
1843 Element prevElement = _exportedElements[name]; | 1793 Element prevElement = _exportedElements[name]; |
1844 if (element != null && prevElement != null && prevElement != element) { | 1794 if (element != null && prevElement != null && prevElement != element) { |
1845 _errorReporter.reportErrorForNode( | 1795 _errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_EXPORT, |
1846 CompileTimeErrorCode.AMBIGUOUS_EXPORT, | 1796 node, [ |
1847 node, | 1797 name, |
1848 [ | 1798 prevElement.library.definingCompilationUnit.displayName, |
1849 name, | 1799 element.library.definingCompilationUnit.displayName |
1850 prevElement.library.definingCompilationUnit.displayName, | 1800 ]); |
1851 element.library.definingCompilationUnit.displayName]); | |
1852 return true; | 1801 return true; |
1853 } else { | 1802 } else { |
1854 _exportedElements[name] = element; | 1803 _exportedElements[name] = element; |
1855 } | 1804 } |
1856 } | 1805 } |
1857 return false; | 1806 return false; |
1858 } | 1807 } |
1859 | 1808 |
1860 /** | 1809 /** |
1861 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. | 1810 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. |
1862 * | 1811 * |
1863 * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAss
ignable. | 1812 * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAss
ignable. |
1864 * | 1813 * |
1865 * @param expression the expression to evaluate | 1814 * @param expression the expression to evaluate |
1866 * @param expectedStaticType the expected static type of the parameter | 1815 * @param expectedStaticType the expected static type of the parameter |
1867 * @param actualStaticType the actual static type of the argument | 1816 * @param actualStaticType the actual static type of the argument |
1868 * @param expectedPropagatedType the expected propagated type of the parameter
, may be | 1817 * @param expectedPropagatedType the expected propagated type of the parameter
, may be |
1869 * `null` | 1818 * `null` |
1870 * @param actualPropagatedType the expected propagated type of the parameter,
may be `null` | 1819 * @param actualPropagatedType the expected propagated type of the parameter,
may be `null` |
1871 * @return `true` if and only if an error code is generated on the passed node | 1820 * @return `true` if and only if an error code is generated on the passed node |
1872 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], | 1821 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], |
1873 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], | 1822 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], |
1874 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], | 1823 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], |
1875 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], | 1824 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], |
1876 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], | 1825 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], |
1877 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and | 1826 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and |
1878 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. | 1827 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. |
1879 */ | 1828 */ |
1880 bool _checkForArgumentTypeNotAssignable(Expression expression, | 1829 bool _checkForArgumentTypeNotAssignable(Expression expression, |
1881 DartType expectedStaticType, DartType actualStaticType, ErrorCode errorCod
e) { | 1830 DartType expectedStaticType, DartType actualStaticType, |
| 1831 ErrorCode errorCode) { |
1882 // | 1832 // |
1883 // Warning case: test static type information | 1833 // Warning case: test static type information |
1884 // | 1834 // |
1885 if (actualStaticType != null && expectedStaticType != null) { | 1835 if (actualStaticType != null && expectedStaticType != null) { |
1886 if (!actualStaticType.isAssignableTo(expectedStaticType)) { | 1836 if (!actualStaticType.isAssignableTo(expectedStaticType)) { |
1887 _errorReporter.reportTypeErrorForNode( | 1837 _errorReporter.reportTypeErrorForNode( |
1888 errorCode, | 1838 errorCode, expression, [actualStaticType, expectedStaticType]); |
1889 expression, | |
1890 [actualStaticType, expectedStaticType]); | |
1891 return true; | 1839 return true; |
1892 } | 1840 } |
1893 } | 1841 } |
1894 return false; | 1842 return false; |
1895 } | 1843 } |
1896 | 1844 |
1897 /** | 1845 /** |
1898 * This verifies that the passed argument can be assigned to its corresponding
parameter. | 1846 * This verifies that the passed argument can be assigned to its corresponding
parameter. |
1899 * | 1847 * |
1900 * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAss
ignableForArgument. | 1848 * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAss
ignableForArgument. |
1901 * | 1849 * |
1902 * @param argument the argument to evaluate | 1850 * @param argument the argument to evaluate |
1903 * @return `true` if and only if an error code is generated on the passed node | 1851 * @return `true` if and only if an error code is generated on the passed node |
1904 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. | 1852 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. |
1905 */ | 1853 */ |
1906 bool _checkForArgumentTypeNotAssignableForArgument(Expression argument) { | 1854 bool _checkForArgumentTypeNotAssignableForArgument(Expression argument) { |
1907 if (argument == null) { | 1855 if (argument == null) { |
1908 return false; | 1856 return false; |
1909 } | 1857 } |
1910 ParameterElement staticParameterElement = argument.staticParameterElement; | 1858 ParameterElement staticParameterElement = argument.staticParameterElement; |
1911 DartType staticParameterType = | 1859 DartType staticParameterType = |
1912 staticParameterElement == null ? null : staticParameterElement.type; | 1860 staticParameterElement == null ? null : staticParameterElement.type; |
1913 return _checkForArgumentTypeNotAssignableWithExpectedTypes( | 1861 return _checkForArgumentTypeNotAssignableWithExpectedTypes(argument, |
1914 argument, | 1862 staticParameterType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); |
1915 staticParameterType, | |
1916 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); | |
1917 } | 1863 } |
1918 | 1864 |
1919 /** | 1865 /** |
1920 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. | 1866 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. |
1921 * | 1867 * |
1922 * This method corresponds to | 1868 * This method corresponds to |
1923 * BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes. | 1869 * BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes. |
1924 * | 1870 * |
1925 * @param expression the expression to evaluate | 1871 * @param expression the expression to evaluate |
1926 * @param expectedStaticType the expected static type | 1872 * @param expectedStaticType the expected static type |
1927 * @param expectedPropagatedType the expected propagated type, may be `null` | 1873 * @param expectedPropagatedType the expected propagated type, may be `null` |
1928 * @return `true` if and only if an error code is generated on the passed node | 1874 * @return `true` if and only if an error code is generated on the passed node |
1929 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], | 1875 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], |
1930 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], | 1876 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], |
1931 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], | 1877 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], |
1932 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], | 1878 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], |
1933 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], | 1879 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], |
1934 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and | 1880 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and |
1935 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. | 1881 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. |
1936 */ | 1882 */ |
1937 bool | 1883 bool _checkForArgumentTypeNotAssignableWithExpectedTypes( |
1938 _checkForArgumentTypeNotAssignableWithExpectedTypes(Expression expression, | 1884 Expression expression, DartType expectedStaticType, |
1939 DartType expectedStaticType, ErrorCode errorCode) => | 1885 ErrorCode errorCode) => _checkForArgumentTypeNotAssignable( |
1940 _checkForArgumentTypeNotAssignable( | 1886 expression, expectedStaticType, getStaticType(expression), errorCode); |
1941 expression, | |
1942 expectedStaticType, | |
1943 getStaticType(expression), | |
1944 errorCode); | |
1945 | 1887 |
1946 /** | 1888 /** |
1947 * This verifies that the passed arguments can be assigned to their correspond
ing parameters. | 1889 * This verifies that the passed arguments can be assigned to their correspond
ing parameters. |
1948 * | 1890 * |
1949 * This method corresponds to BestPracticesVerifier.checkForArgumentTypesNotAs
signableInList. | 1891 * This method corresponds to BestPracticesVerifier.checkForArgumentTypesNotAs
signableInList. |
1950 * | 1892 * |
1951 * @param node the arguments to evaluate | 1893 * @param node the arguments to evaluate |
1952 * @return `true` if and only if an error code is generated on the passed node | 1894 * @return `true` if and only if an error code is generated on the passed node |
1953 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. | 1895 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. |
1954 */ | 1896 */ |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2016 } | 1958 } |
2017 // check if element is assignable | 1959 // check if element is assignable |
2018 if (element is PropertyAccessorElement) { | 1960 if (element is PropertyAccessorElement) { |
2019 PropertyAccessorElement accessor = element as PropertyAccessorElement; | 1961 PropertyAccessorElement accessor = element as PropertyAccessorElement; |
2020 element = accessor.variable; | 1962 element = accessor.variable; |
2021 } | 1963 } |
2022 if (element is VariableElement) { | 1964 if (element is VariableElement) { |
2023 VariableElement variable = element as VariableElement; | 1965 VariableElement variable = element as VariableElement; |
2024 if (variable.isConst) { | 1966 if (variable.isConst) { |
2025 _errorReporter.reportErrorForNode( | 1967 _errorReporter.reportErrorForNode( |
2026 StaticWarningCode.ASSIGNMENT_TO_CONST, | 1968 StaticWarningCode.ASSIGNMENT_TO_CONST, expression); |
2027 expression); | |
2028 return true; | 1969 return true; |
2029 } | 1970 } |
2030 if (variable.isFinal) { | 1971 if (variable.isFinal) { |
2031 if (variable is FieldElementImpl && | 1972 if (variable is FieldElementImpl && |
2032 variable.setter == null && | 1973 variable.setter == null && |
2033 variable.isSynthetic) { | 1974 variable.isSynthetic) { |
2034 _errorReporter.reportErrorForNode( | 1975 _errorReporter.reportErrorForNode( |
2035 StaticWarningCode.ASSIGNMENT_TO_FINAL_NO_SETTER, | 1976 StaticWarningCode.ASSIGNMENT_TO_FINAL_NO_SETTER, highlightedNode, |
2036 highlightedNode, | |
2037 [variable.name, variable.enclosingElement.displayName]); | 1977 [variable.name, variable.enclosingElement.displayName]); |
2038 return true; | 1978 return true; |
2039 } | 1979 } |
2040 _errorReporter.reportErrorForNode( | 1980 _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_FINAL, |
2041 StaticWarningCode.ASSIGNMENT_TO_FINAL, | 1981 highlightedNode, [variable.name]); |
2042 highlightedNode, | |
2043 [variable.name]); | |
2044 return true; | 1982 return true; |
2045 } | 1983 } |
2046 return false; | 1984 return false; |
2047 } | 1985 } |
2048 if (element is FunctionElement) { | 1986 if (element is FunctionElement) { |
2049 _errorReporter.reportErrorForNode( | 1987 _errorReporter.reportErrorForNode( |
2050 StaticWarningCode.ASSIGNMENT_TO_FUNCTION, | 1988 StaticWarningCode.ASSIGNMENT_TO_FUNCTION, expression); |
2051 expression); | |
2052 return true; | 1989 return true; |
2053 } | 1990 } |
2054 if (element is MethodElement) { | 1991 if (element is MethodElement) { |
2055 _errorReporter.reportErrorForNode( | 1992 _errorReporter.reportErrorForNode( |
2056 StaticWarningCode.ASSIGNMENT_TO_METHOD, | 1993 StaticWarningCode.ASSIGNMENT_TO_METHOD, expression); |
2057 expression); | |
2058 return true; | 1994 return true; |
2059 } | 1995 } |
2060 return false; | 1996 return false; |
2061 } | 1997 } |
2062 | 1998 |
2063 /** | 1999 /** |
2064 * This verifies that the passed identifier is not a keyword, and generates th
e passed error code | 2000 * This verifies that the passed identifier is not a keyword, and generates th
e passed error code |
2065 * on the identifier if it is a keyword. | 2001 * on the identifier if it is a keyword. |
2066 * | 2002 * |
2067 * @param identifier the identifier to check to ensure that it is not a keywor
d | 2003 * @param identifier the identifier to check to ensure that it is not a keywor
d |
2068 * @param errorCode if the passed identifier is a keyword then this error code
is created on the | 2004 * @param errorCode if the passed identifier is a keyword then this error code
is created on the |
2069 * identifier, the error code will be one of | 2005 * identifier, the error code will be one of |
2070 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME], | 2006 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME], |
2071 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME]
or | 2007 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME]
or |
2072 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME] | 2008 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME] |
2073 * @return `true` if and only if an error code is generated on the passed node | 2009 * @return `true` if and only if an error code is generated on the passed node |
2074 * See [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME], | 2010 * See [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME], |
2075 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME], and | 2011 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME], and |
2076 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]. | 2012 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]. |
2077 */ | 2013 */ |
2078 bool _checkForBuiltInIdentifierAsName(SimpleIdentifier identifier, | 2014 bool _checkForBuiltInIdentifierAsName( |
2079 ErrorCode errorCode) { | 2015 SimpleIdentifier identifier, ErrorCode errorCode) { |
2080 sc.Token token = identifier.token; | 2016 sc.Token token = identifier.token; |
2081 if (token.type == sc.TokenType.KEYWORD) { | 2017 if (token.type == sc.TokenType.KEYWORD) { |
2082 _errorReporter.reportErrorForNode( | 2018 _errorReporter.reportErrorForNode( |
2083 errorCode, | 2019 errorCode, identifier, [identifier.name]); |
2084 identifier, | |
2085 [identifier.name]); | |
2086 return true; | 2020 return true; |
2087 } | 2021 } |
2088 return false; | 2022 return false; |
2089 } | 2023 } |
2090 | 2024 |
2091 /** | 2025 /** |
2092 * This verifies that the given switch case is terminated with 'break', 'conti
nue', 'return' or | 2026 * This verifies that the given switch case is terminated with 'break', 'conti
nue', 'return' or |
2093 * 'throw'. | 2027 * 'throw'. |
2094 * | 2028 * |
2095 * @param node the switch case to evaluate | 2029 * @param node the switch case to evaluate |
(...skipping 25 matching lines...) Expand all Loading... |
2121 // terminated with 'throw' expression | 2055 // terminated with 'throw' expression |
2122 if (statement is ExpressionStatement) { | 2056 if (statement is ExpressionStatement) { |
2123 Expression expression = statement.expression; | 2057 Expression expression = statement.expression; |
2124 if (expression is ThrowExpression) { | 2058 if (expression is ThrowExpression) { |
2125 return false; | 2059 return false; |
2126 } | 2060 } |
2127 } | 2061 } |
2128 } | 2062 } |
2129 // report error | 2063 // report error |
2130 _errorReporter.reportErrorForToken( | 2064 _errorReporter.reportErrorForToken( |
2131 StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, | 2065 StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, node.keyword); |
2132 node.keyword); | |
2133 return true; | 2066 return true; |
2134 } | 2067 } |
2135 | 2068 |
2136 /** | 2069 /** |
2137 * This verifies that the switch cases in the given switch statement is termin
ated with 'break', | 2070 * This verifies that the switch cases in the given switch statement is termin
ated with 'break', |
2138 * 'continue', 'return' or 'throw'. | 2071 * 'continue', 'return' or 'throw'. |
2139 * | 2072 * |
2140 * @param node the switch statement containing the cases to be checked | 2073 * @param node the switch statement containing the cases to be checked |
2141 * @return `true` if and only if an error code is generated on the passed node | 2074 * @return `true` if and only if an error code is generated on the passed node |
2142 * See [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]. | 2075 * See [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]. |
(...skipping 20 matching lines...) Expand all Loading... |
2163 * See [StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER]. | 2096 * See [StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER]. |
2164 */ | 2097 */ |
2165 bool _checkForConcreteClassWithAbstractMember(MethodDeclaration node) { | 2098 bool _checkForConcreteClassWithAbstractMember(MethodDeclaration node) { |
2166 if (node.isAbstract && | 2099 if (node.isAbstract && |
2167 _enclosingClass != null && | 2100 _enclosingClass != null && |
2168 !_enclosingClass.isAbstract) { | 2101 !_enclosingClass.isAbstract) { |
2169 SimpleIdentifier nameNode = node.name; | 2102 SimpleIdentifier nameNode = node.name; |
2170 String memberName = nameNode.name; | 2103 String memberName = nameNode.name; |
2171 ExecutableElement overriddenMember; | 2104 ExecutableElement overriddenMember; |
2172 if (node.isGetter) { | 2105 if (node.isGetter) { |
2173 overriddenMember = | 2106 overriddenMember = _enclosingClass.lookUpInheritedConcreteGetter( |
2174 _enclosingClass.lookUpInheritedConcreteGetter(memberName, _currentLi
brary); | 2107 memberName, _currentLibrary); |
2175 } else if (node.isSetter) { | 2108 } else if (node.isSetter) { |
2176 overriddenMember = | 2109 overriddenMember = _enclosingClass.lookUpInheritedConcreteSetter( |
2177 _enclosingClass.lookUpInheritedConcreteSetter(memberName, _currentLi
brary); | 2110 memberName, _currentLibrary); |
2178 } else { | 2111 } else { |
2179 overriddenMember = | 2112 overriddenMember = _enclosingClass.lookUpInheritedConcreteMethod( |
2180 _enclosingClass.lookUpInheritedConcreteMethod(memberName, _currentLi
brary); | 2113 memberName, _currentLibrary); |
2181 } | 2114 } |
2182 if (overriddenMember == null) { | 2115 if (overriddenMember == null) { |
2183 _errorReporter.reportErrorForNode( | 2116 _errorReporter.reportErrorForNode( |
2184 StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, | 2117 StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, nameNode, [ |
2185 nameNode, | 2118 memberName, |
2186 [memberName, _enclosingClass.displayName]); | 2119 _enclosingClass.displayName |
| 2120 ]); |
2187 return true; | 2121 return true; |
2188 } | 2122 } |
2189 } | 2123 } |
2190 return false; | 2124 return false; |
2191 } | 2125 } |
2192 | 2126 |
2193 /** | 2127 /** |
2194 * This verifies all possible conflicts of the constructor name with other con
structors and | 2128 * This verifies all possible conflicts of the constructor name with other con
structors and |
2195 * members of the same class. | 2129 * members of the same class. |
2196 * | 2130 * |
2197 * @param node the constructor declaration to evaluate | 2131 * @param node the constructor declaration to evaluate |
2198 * @param constructorElement the constructor element | 2132 * @param constructorElement the constructor element |
2199 * @return `true` if and only if an error code is generated on the passed node | 2133 * @return `true` if and only if an error code is generated on the passed node |
2200 * See [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT], | 2134 * See [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT], |
2201 * [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME], | 2135 * [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME], |
2202 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD], and | 2136 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD], and |
2203 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD]. | 2137 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD]. |
2204 */ | 2138 */ |
2205 bool _checkForConflictingConstructorNameAndMember(ConstructorDeclaration node, | 2139 bool _checkForConflictingConstructorNameAndMember( |
2206 ConstructorElement constructorElement) { | 2140 ConstructorDeclaration node, ConstructorElement constructorElement) { |
2207 SimpleIdentifier constructorName = node.name; | 2141 SimpleIdentifier constructorName = node.name; |
2208 String name = constructorElement.name; | 2142 String name = constructorElement.name; |
2209 ClassElement classElement = constructorElement.enclosingElement; | 2143 ClassElement classElement = constructorElement.enclosingElement; |
2210 // constructors | 2144 // constructors |
2211 List<ConstructorElement> constructors = classElement.constructors; | 2145 List<ConstructorElement> constructors = classElement.constructors; |
2212 for (ConstructorElement otherConstructor in constructors) { | 2146 for (ConstructorElement otherConstructor in constructors) { |
2213 if (identical(otherConstructor, constructorElement)) { | 2147 if (identical(otherConstructor, constructorElement)) { |
2214 continue; | 2148 continue; |
2215 } | 2149 } |
2216 if (name == otherConstructor.name) { | 2150 if (name == otherConstructor.name) { |
2217 if (name == null || name.length == 0) { | 2151 if (name == null || name.length == 0) { |
2218 _errorReporter.reportErrorForNode( | 2152 _errorReporter.reportErrorForNode( |
2219 CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, | 2153 CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, node); |
2220 node); | |
2221 } else { | 2154 } else { |
2222 _errorReporter.reportErrorForNode( | 2155 _errorReporter.reportErrorForNode( |
2223 CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME, | 2156 CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME, node, [name]); |
2224 node, | |
2225 [name]); | |
2226 } | 2157 } |
2227 return true; | 2158 return true; |
2228 } | 2159 } |
2229 } | 2160 } |
2230 // conflict with class member | 2161 // conflict with class member |
2231 if (constructorName != null && | 2162 if (constructorName != null && |
2232 constructorElement != null && | 2163 constructorElement != null && |
2233 !constructorName.isSynthetic) { | 2164 !constructorName.isSynthetic) { |
2234 // fields | 2165 // fields |
2235 FieldElement field = classElement.getField(name); | 2166 FieldElement field = classElement.getField(name); |
2236 if (field != null) { | 2167 if (field != null) { |
2237 _errorReporter.reportErrorForNode( | 2168 _errorReporter.reportErrorForNode( |
2238 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, | 2169 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, node, [ |
2239 node, | 2170 name |
2240 [name]); | 2171 ]); |
2241 return true; | 2172 return true; |
2242 } | 2173 } |
2243 // methods | 2174 // methods |
2244 MethodElement method = classElement.getMethod(name); | 2175 MethodElement method = classElement.getMethod(name); |
2245 if (method != null) { | 2176 if (method != null) { |
2246 _errorReporter.reportErrorForNode( | 2177 _errorReporter.reportErrorForNode( |
2247 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, | 2178 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, |
2248 node, | |
2249 [name]); | 2179 [name]); |
2250 return true; | 2180 return true; |
2251 } | 2181 } |
2252 } | 2182 } |
2253 return false; | 2183 return false; |
2254 } | 2184 } |
2255 | 2185 |
2256 /** | 2186 /** |
2257 * This verifies that the [enclosingClass] does not have a method and getter p
air with the | 2187 * This verifies that the [enclosingClass] does not have a method and getter p
air with the |
2258 * same name on, via inheritance. | 2188 * same name on, via inheritance. |
(...skipping 12 matching lines...) Expand all Loading... |
2271 String name = method.name; | 2201 String name = method.name; |
2272 // find inherited property accessor (and can be only getter) | 2202 // find inherited property accessor (and can be only getter) |
2273 ExecutableElement inherited = | 2203 ExecutableElement inherited = |
2274 _inheritanceManager.lookupInheritance(_enclosingClass, name); | 2204 _inheritanceManager.lookupInheritance(_enclosingClass, name); |
2275 if (inherited is! PropertyAccessorElement) { | 2205 if (inherited is! PropertyAccessorElement) { |
2276 continue; | 2206 continue; |
2277 } | 2207 } |
2278 // report problem | 2208 // report problem |
2279 hasProblem = true; | 2209 hasProblem = true; |
2280 _errorReporter.reportErrorForOffset( | 2210 _errorReporter.reportErrorForOffset( |
2281 CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD, | 2211 CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD, method.nameOffset, |
2282 method.nameOffset, | 2212 name.length, [ |
2283 name.length, | 2213 _enclosingClass.displayName, |
2284 [_enclosingClass.displayName, inherited.enclosingElement.displayName,
name]); | 2214 inherited.enclosingElement.displayName, |
| 2215 name |
| 2216 ]); |
2285 } | 2217 } |
2286 // getter declared in the enclosing class vs. inherited method | 2218 // getter declared in the enclosing class vs. inherited method |
2287 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { | 2219 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { |
2288 if (!accessor.isGetter) { | 2220 if (!accessor.isGetter) { |
2289 continue; | 2221 continue; |
2290 } | 2222 } |
2291 String name = accessor.name; | 2223 String name = accessor.name; |
2292 // find inherited method | 2224 // find inherited method |
2293 ExecutableElement inherited = | 2225 ExecutableElement inherited = |
2294 _inheritanceManager.lookupInheritance(_enclosingClass, name); | 2226 _inheritanceManager.lookupInheritance(_enclosingClass, name); |
2295 if (inherited is! MethodElement) { | 2227 if (inherited is! MethodElement) { |
2296 continue; | 2228 continue; |
2297 } | 2229 } |
2298 // report problem | 2230 // report problem |
2299 hasProblem = true; | 2231 hasProblem = true; |
2300 _errorReporter.reportErrorForOffset( | 2232 _errorReporter.reportErrorForOffset( |
2301 CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER, | 2233 CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER, |
2302 accessor.nameOffset, | 2234 accessor.nameOffset, name.length, [ |
2303 name.length, | 2235 _enclosingClass.displayName, |
2304 [_enclosingClass.displayName, inherited.enclosingElement.displayName,
name]); | 2236 inherited.enclosingElement.displayName, |
| 2237 name |
| 2238 ]); |
2305 } | 2239 } |
2306 // done | 2240 // done |
2307 return hasProblem; | 2241 return hasProblem; |
2308 } | 2242 } |
2309 | 2243 |
2310 /** | 2244 /** |
2311 * This verifies that the superclass of the [enclosingClass] does not declare
accessible | 2245 * This verifies that the superclass of the [enclosingClass] does not declare
accessible |
2312 * static members with the same name as the instance getters/setters declared
in | 2246 * static members with the same name as the instance getters/setters declared
in |
2313 * [enclosingClass]. | 2247 * [enclosingClass]. |
2314 * | 2248 * |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2358 } | 2292 } |
2359 // prepare "super" type to report its name | 2293 // prepare "super" type to report its name |
2360 ClassElement superElementClass = | 2294 ClassElement superElementClass = |
2361 superElement.enclosingElement as ClassElement; | 2295 superElement.enclosingElement as ClassElement; |
2362 InterfaceType superElementType = superElementClass.type; | 2296 InterfaceType superElementType = superElementClass.type; |
2363 // report problem | 2297 // report problem |
2364 hasProblem = true; | 2298 hasProblem = true; |
2365 if (getter) { | 2299 if (getter) { |
2366 _errorReporter.reportErrorForElement( | 2300 _errorReporter.reportErrorForElement( |
2367 StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, | 2301 StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, |
2368 accessor, | 2302 accessor, [superElementType.displayName]); |
2369 [superElementType.displayName]); | |
2370 } else { | 2303 } else { |
2371 _errorReporter.reportErrorForElement( | 2304 _errorReporter.reportErrorForElement( |
2372 StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, | 2305 StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, |
2373 accessor, | 2306 accessor, [superElementType.displayName]); |
2374 [superElementType.displayName]); | |
2375 } | 2307 } |
2376 } | 2308 } |
2377 // done | 2309 // done |
2378 return hasProblem; | 2310 return hasProblem; |
2379 } | 2311 } |
2380 | 2312 |
2381 /** | 2313 /** |
2382 * This verifies that the enclosing class does not have a setter with the same
name as the passed | 2314 * This verifies that the enclosing class does not have a setter with the same
name as the passed |
2383 * instance method declaration. | 2315 * instance method declaration. |
2384 * | 2316 * |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2421 // member is a method or a setter for | 2353 // member is a method or a setter for |
2422 // StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER warning. | 2354 // StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER warning. |
2423 if (isMethod) { | 2355 if (isMethod) { |
2424 String setterName = "${name.name}="; | 2356 String setterName = "${name.name}="; |
2425 Element enclosingElementOfSetter = null; | 2357 Element enclosingElementOfSetter = null; |
2426 ClassMember conflictingSetter = memberHashMap[setterName]; | 2358 ClassMember conflictingSetter = memberHashMap[setterName]; |
2427 if (conflictingSetter != null) { | 2359 if (conflictingSetter != null) { |
2428 enclosingElementOfSetter = | 2360 enclosingElementOfSetter = |
2429 conflictingSetter.element.enclosingElement; | 2361 conflictingSetter.element.enclosingElement; |
2430 } else { | 2362 } else { |
2431 ExecutableElement elementFromInheritance = | 2363 ExecutableElement elementFromInheritance = _inheritanceManager |
2432 _inheritanceManager.lookupInheritance(_enclosingClass, setterNam
e); | 2364 .lookupInheritance(_enclosingClass, setterName); |
2433 if (elementFromInheritance != null) { | 2365 if (elementFromInheritance != null) { |
2434 enclosingElementOfSetter = | 2366 enclosingElementOfSetter = |
2435 elementFromInheritance.enclosingElement; | 2367 elementFromInheritance.enclosingElement; |
2436 } | 2368 } |
2437 } | 2369 } |
2438 if (enclosingElementOfSetter != null) { | 2370 if (enclosingElementOfSetter != null) { |
2439 // report problem | 2371 // report problem |
2440 _errorReporter.reportErrorForNode( | 2372 _errorReporter.reportErrorForNode( |
2441 StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER, | 2373 StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER, name, [ |
2442 name, | 2374 _enclosingClass.displayName, |
2443 [_enclosingClass.displayName, name.name, enclosingElementOfSette
r.displayName]); | 2375 name.name, |
| 2376 enclosingElementOfSetter.displayName |
| 2377 ]); |
2444 foundError = true; | 2378 foundError = true; |
2445 addThisMemberToTheMap = false; | 2379 addThisMemberToTheMap = false; |
2446 } | 2380 } |
2447 } else if (isSetter) { | 2381 } else if (isSetter) { |
2448 String methodName = name.name; | 2382 String methodName = name.name; |
2449 ClassMember conflictingMethod = memberHashMap[methodName]; | 2383 ClassMember conflictingMethod = memberHashMap[methodName]; |
2450 if (conflictingMethod != null && | 2384 if (conflictingMethod != null && |
2451 conflictingMethod is MethodDeclaration && | 2385 conflictingMethod is MethodDeclaration && |
2452 !conflictingMethod.isGetter) { | 2386 !conflictingMethod.isGetter) { |
2453 // report problem | 2387 // report problem |
2454 _errorReporter.reportErrorForNode( | 2388 _errorReporter.reportErrorForNode( |
2455 StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2, | 2389 StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2, name, |
2456 name, | |
2457 [_enclosingClass.displayName, name.name]); | 2390 [_enclosingClass.displayName, name.name]); |
2458 foundError = true; | 2391 foundError = true; |
2459 addThisMemberToTheMap = false; | 2392 addThisMemberToTheMap = false; |
2460 } | 2393 } |
2461 } | 2394 } |
2462 // Finally, add this member into the HashMap. | 2395 // Finally, add this member into the HashMap. |
2463 if (addThisMemberToTheMap) { | 2396 if (addThisMemberToTheMap) { |
2464 if (method.isSetter) { | 2397 if (method.isSetter) { |
2465 memberHashMap["${name.name}="] = method; | 2398 memberHashMap["${name.name}="] = method; |
2466 } else { | 2399 } else { |
2467 memberHashMap[name.name] = method; | 2400 memberHashMap[name.name] = method; |
2468 } | 2401 } |
2469 } | 2402 } |
2470 } | 2403 } |
2471 } | 2404 } |
2472 return foundError; | 2405 return foundError; |
2473 } | 2406 } |
2474 | 2407 |
2475 /** | 2408 /** |
2476 * This verifies that the enclosing class does not have an instance member wit
h the same name as | 2409 * This verifies that the enclosing class does not have an instance member wit
h the same name as |
2477 * the passed static getter method declaration. | 2410 * the passed static getter method declaration. |
2478 * | 2411 * |
2479 * @param node the method declaration to evaluate | 2412 * @param node the method declaration to evaluate |
2480 * @return `true` if and only if an error code is generated on the passed node | 2413 * @return `true` if and only if an error code is generated on the passed node |
2481 * See [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]. | 2414 * See [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]. |
2482 */ | 2415 */ |
2483 bool | 2416 bool _checkForConflictingStaticGetterAndInstanceSetter( |
2484 _checkForConflictingStaticGetterAndInstanceSetter(MethodDeclaration node)
{ | 2417 MethodDeclaration node) { |
2485 if (!node.isStatic) { | 2418 if (!node.isStatic) { |
2486 return false; | 2419 return false; |
2487 } | 2420 } |
2488 // prepare name | 2421 // prepare name |
2489 SimpleIdentifier nameNode = node.name; | 2422 SimpleIdentifier nameNode = node.name; |
2490 if (nameNode == null) { | 2423 if (nameNode == null) { |
2491 return false; | 2424 return false; |
2492 } | 2425 } |
2493 String name = nameNode.name; | 2426 String name = nameNode.name; |
2494 // prepare enclosing type | 2427 // prepare enclosing type |
(...skipping 10 matching lines...) Expand all Loading... |
2505 // OK, also static | 2438 // OK, also static |
2506 if (setter.isStatic) { | 2439 if (setter.isStatic) { |
2507 return false; | 2440 return false; |
2508 } | 2441 } |
2509 // prepare "setter" type to report its name | 2442 // prepare "setter" type to report its name |
2510 ClassElement setterClass = setter.enclosingElement as ClassElement; | 2443 ClassElement setterClass = setter.enclosingElement as ClassElement; |
2511 InterfaceType setterType = setterClass.type; | 2444 InterfaceType setterType = setterClass.type; |
2512 // report problem | 2445 // report problem |
2513 _errorReporter.reportErrorForNode( | 2446 _errorReporter.reportErrorForNode( |
2514 StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER, | 2447 StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER, |
2515 nameNode, | 2448 nameNode, [setterType.displayName]); |
2516 [setterType.displayName]); | |
2517 return true; | 2449 return true; |
2518 } | 2450 } |
2519 | 2451 |
2520 /** | 2452 /** |
2521 * This verifies that the enclosing class does not have an instance member wit
h the same name as | 2453 * This verifies that the enclosing class does not have an instance member wit
h the same name as |
2522 * the passed static getter method declaration. | 2454 * the passed static getter method declaration. |
2523 * | 2455 * |
2524 * @param node the method declaration to evaluate | 2456 * @param node the method declaration to evaluate |
2525 * @return `true` if and only if an error code is generated on the passed node | 2457 * @return `true` if and only if an error code is generated on the passed node |
2526 * See [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]. | 2458 * See [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]. |
2527 */ | 2459 */ |
2528 bool | 2460 bool _checkForConflictingStaticSetterAndInstanceMember( |
2529 _checkForConflictingStaticSetterAndInstanceMember(MethodDeclaration node)
{ | 2461 MethodDeclaration node) { |
2530 if (!node.isStatic) { | 2462 if (!node.isStatic) { |
2531 return false; | 2463 return false; |
2532 } | 2464 } |
2533 // prepare name | 2465 // prepare name |
2534 SimpleIdentifier nameNode = node.name; | 2466 SimpleIdentifier nameNode = node.name; |
2535 if (nameNode == null) { | 2467 if (nameNode == null) { |
2536 return false; | 2468 return false; |
2537 } | 2469 } |
2538 String name = nameNode.name; | 2470 String name = nameNode.name; |
2539 // prepare enclosing type | 2471 // prepare enclosing type |
(...skipping 16 matching lines...) Expand all Loading... |
2556 // OK, also static | 2488 // OK, also static |
2557 if (member.isStatic) { | 2489 if (member.isStatic) { |
2558 return false; | 2490 return false; |
2559 } | 2491 } |
2560 // prepare "member" type to report its name | 2492 // prepare "member" type to report its name |
2561 ClassElement memberClass = member.enclosingElement as ClassElement; | 2493 ClassElement memberClass = member.enclosingElement as ClassElement; |
2562 InterfaceType memberType = memberClass.type; | 2494 InterfaceType memberType = memberClass.type; |
2563 // report problem | 2495 // report problem |
2564 _errorReporter.reportErrorForNode( | 2496 _errorReporter.reportErrorForNode( |
2565 StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER, | 2497 StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER, |
2566 nameNode, | 2498 nameNode, [memberType.displayName]); |
2567 [memberType.displayName]); | |
2568 return true; | 2499 return true; |
2569 } | 2500 } |
2570 | 2501 |
2571 /** | 2502 /** |
2572 * This verifies all conflicts between type variable and enclosing class. TODO
(scheglov) | 2503 * This verifies all conflicts between type variable and enclosing class. TODO
(scheglov) |
2573 * | 2504 * |
2574 * @param node the class declaration to evaluate | 2505 * @param node the class declaration to evaluate |
2575 * @return `true` if and only if an error code is generated on the passed node | 2506 * @return `true` if and only if an error code is generated on the passed node |
2576 * See [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS], and | 2507 * See [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS], and |
2577 * [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]. | 2508 * [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]. |
2578 */ | 2509 */ |
2579 bool _checkForConflictingTypeVariableErrorCodes(ClassDeclaration node) { | 2510 bool _checkForConflictingTypeVariableErrorCodes(ClassDeclaration node) { |
2580 bool problemReported = false; | 2511 bool problemReported = false; |
2581 for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) { | 2512 for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) { |
2582 String name = typeParameter.name; | 2513 String name = typeParameter.name; |
2583 // name is same as the name of the enclosing class | 2514 // name is same as the name of the enclosing class |
2584 if (_enclosingClass.name == name) { | 2515 if (_enclosingClass.name == name) { |
2585 _errorReporter.reportErrorForOffset( | 2516 _errorReporter.reportErrorForOffset( |
2586 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, | 2517 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, |
2587 typeParameter.nameOffset, | 2518 typeParameter.nameOffset, name.length, [name]); |
2588 name.length, | |
2589 [name]); | |
2590 problemReported = true; | 2519 problemReported = true; |
2591 } | 2520 } |
2592 // check members | 2521 // check members |
2593 if (_enclosingClass.getMethod(name) != null || | 2522 if (_enclosingClass.getMethod(name) != null || |
2594 _enclosingClass.getGetter(name) != null || | 2523 _enclosingClass.getGetter(name) != null || |
2595 _enclosingClass.getSetter(name) != null) { | 2524 _enclosingClass.getSetter(name) != null) { |
2596 _errorReporter.reportErrorForOffset( | 2525 _errorReporter.reportErrorForOffset( |
2597 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER, | 2526 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER, |
2598 typeParameter.nameOffset, | 2527 typeParameter.nameOffset, name.length, [name]); |
2599 name.length, | |
2600 [name]); | |
2601 problemReported = true; | 2528 problemReported = true; |
2602 } | 2529 } |
2603 } | 2530 } |
2604 return problemReported; | 2531 return problemReported; |
2605 } | 2532 } |
2606 | 2533 |
2607 /** | 2534 /** |
2608 * This verifies that if the passed constructor declaration is 'const' then th
ere are no | 2535 * This verifies that if the passed constructor declaration is 'const' then th
ere are no |
2609 * invocations of non-'const' super constructors. | 2536 * invocations of non-'const' super constructors. |
2610 * | 2537 * |
2611 * @param node the constructor declaration to evaluate | 2538 * @param node the constructor declaration to evaluate |
2612 * @return `true` if and only if an error code is generated on the passed node | 2539 * @return `true` if and only if an error code is generated on the passed node |
2613 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]. | 2540 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]. |
2614 */ | 2541 */ |
2615 bool _checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) { | 2542 bool _checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) { |
2616 if (!_isEnclosingConstructorConst) { | 2543 if (!_isEnclosingConstructorConst) { |
2617 return false; | 2544 return false; |
2618 } | 2545 } |
2619 // OK, const factory, checked elsewhere | 2546 // OK, const factory, checked elsewhere |
2620 if (node.factoryKeyword != null) { | 2547 if (node.factoryKeyword != null) { |
2621 return false; | 2548 return false; |
2622 } | 2549 } |
2623 // check for mixins | 2550 // check for mixins |
2624 if (_enclosingClass.mixins.length != 0) { | 2551 if (_enclosingClass.mixins.length != 0) { |
2625 _errorReporter.reportErrorForNode( | 2552 _errorReporter.reportErrorForNode( |
2626 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN, | 2553 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN, node.returnType); |
2627 node.returnType); | |
2628 return true; | 2554 return true; |
2629 } | 2555 } |
2630 // try to find and check super constructor invocation | 2556 // try to find and check super constructor invocation |
2631 for (ConstructorInitializer initializer in node.initializers) { | 2557 for (ConstructorInitializer initializer in node.initializers) { |
2632 if (initializer is SuperConstructorInvocation) { | 2558 if (initializer is SuperConstructorInvocation) { |
2633 SuperConstructorInvocation superInvocation = initializer; | 2559 SuperConstructorInvocation superInvocation = initializer; |
2634 ConstructorElement element = superInvocation.staticElement; | 2560 ConstructorElement element = superInvocation.staticElement; |
2635 if (element == null || element.isConst) { | 2561 if (element == null || element.isConst) { |
2636 return false; | 2562 return false; |
2637 } | 2563 } |
2638 _errorReporter.reportErrorForNode( | 2564 _errorReporter.reportErrorForNode( |
2639 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, | 2565 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, |
2640 superInvocation, | 2566 superInvocation, [element.enclosingElement.displayName]); |
2641 [element.enclosingElement.displayName]); | |
2642 return true; | 2567 return true; |
2643 } | 2568 } |
2644 } | 2569 } |
2645 // no explicit super constructor invocation, check default constructor | 2570 // no explicit super constructor invocation, check default constructor |
2646 InterfaceType supertype = _enclosingClass.supertype; | 2571 InterfaceType supertype = _enclosingClass.supertype; |
2647 if (supertype == null) { | 2572 if (supertype == null) { |
2648 return false; | 2573 return false; |
2649 } | 2574 } |
2650 if (supertype.isObject) { | 2575 if (supertype.isObject) { |
2651 return false; | 2576 return false; |
2652 } | 2577 } |
2653 ConstructorElement unnamedConstructor = | 2578 ConstructorElement unnamedConstructor = |
2654 supertype.element.unnamedConstructor; | 2579 supertype.element.unnamedConstructor; |
2655 if (unnamedConstructor == null) { | 2580 if (unnamedConstructor == null) { |
2656 return false; | 2581 return false; |
2657 } | 2582 } |
2658 if (unnamedConstructor.isConst) { | 2583 if (unnamedConstructor.isConst) { |
2659 return false; | 2584 return false; |
2660 } | 2585 } |
2661 // default constructor is not 'const', report problem | 2586 // default constructor is not 'const', report problem |
2662 _errorReporter.reportErrorForNode( | 2587 _errorReporter.reportErrorForNode( |
2663 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, | 2588 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, |
2664 node.returnType, | 2589 node.returnType, [supertype.displayName]); |
2665 [supertype.displayName]); | |
2666 return true; | 2590 return true; |
2667 } | 2591 } |
2668 | 2592 |
2669 /** | 2593 /** |
2670 * This verifies that if the passed constructor declaration is 'const' then th
ere are no non-final | 2594 * This verifies that if the passed constructor declaration is 'const' then th
ere are no non-final |
2671 * instance variable. | 2595 * instance variable. |
2672 * | 2596 * |
2673 * @param node the constructor declaration to evaluate | 2597 * @param node the constructor declaration to evaluate |
2674 * @param constructorElement the constructor element | 2598 * @param constructorElement the constructor element |
2675 * @return `true` if and only if an error code is generated on the passed node | 2599 * @return `true` if and only if an error code is generated on the passed node |
2676 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]. | 2600 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]. |
2677 */ | 2601 */ |
2678 bool _checkForConstConstructorWithNonFinalField(ConstructorDeclaration node, | 2602 bool _checkForConstConstructorWithNonFinalField( |
2679 ConstructorElement constructorElement) { | 2603 ConstructorDeclaration node, ConstructorElement constructorElement) { |
2680 if (!_isEnclosingConstructorConst) { | 2604 if (!_isEnclosingConstructorConst) { |
2681 return false; | 2605 return false; |
2682 } | 2606 } |
2683 // check if there is non-final field | 2607 // check if there is non-final field |
2684 ClassElement classElement = constructorElement.enclosingElement; | 2608 ClassElement classElement = constructorElement.enclosingElement; |
2685 if (!classElement.hasNonFinalField) { | 2609 if (!classElement.hasNonFinalField) { |
2686 return false; | 2610 return false; |
2687 } | 2611 } |
2688 // report problem | 2612 // report problem |
2689 _errorReporter.reportErrorForNode( | 2613 _errorReporter.reportErrorForNode( |
2690 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, | 2614 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, node); |
2691 node); | |
2692 return true; | 2615 return true; |
2693 } | 2616 } |
2694 | 2617 |
2695 /** | 2618 /** |
2696 * This verifies that the passed 'const' instance creation expression is not c
reating a deferred | 2619 * This verifies that the passed 'const' instance creation expression is not c
reating a deferred |
2697 * type. | 2620 * type. |
2698 * | 2621 * |
2699 * @param node the instance creation expression to evaluate | 2622 * @param node the instance creation expression to evaluate |
2700 * @param constructorName the constructor name, always non-`null` | 2623 * @param constructorName the constructor name, always non-`null` |
2701 * @param typeName the name of the type defining the constructor, always non-`
null` | 2624 * @param typeName the name of the type defining the constructor, always non-`
null` |
2702 * @return `true` if and only if an error code is generated on the passed node | 2625 * @return `true` if and only if an error code is generated on the passed node |
2703 * See [CompileTimeErrorCode.CONST_DEFERRED_CLASS]. | 2626 * See [CompileTimeErrorCode.CONST_DEFERRED_CLASS]. |
2704 */ | 2627 */ |
2705 bool _checkForConstDeferredClass(InstanceCreationExpression node, | 2628 bool _checkForConstDeferredClass(InstanceCreationExpression node, |
2706 ConstructorName constructorName, TypeName typeName) { | 2629 ConstructorName constructorName, TypeName typeName) { |
2707 if (typeName.isDeferred) { | 2630 if (typeName.isDeferred) { |
2708 _errorReporter.reportErrorForNode( | 2631 _errorReporter.reportErrorForNode( |
2709 CompileTimeErrorCode.CONST_DEFERRED_CLASS, | 2632 CompileTimeErrorCode.CONST_DEFERRED_CLASS, constructorName, [ |
2710 constructorName, | 2633 typeName.name.name |
2711 [typeName.name.name]); | 2634 ]); |
2712 return true; | 2635 return true; |
2713 } | 2636 } |
2714 return false; | 2637 return false; |
2715 } | 2638 } |
2716 | 2639 |
2717 /** | 2640 /** |
2718 * This verifies that the passed throw expression is not enclosed in a 'const'
constructor | 2641 * This verifies that the passed throw expression is not enclosed in a 'const'
constructor |
2719 * declaration. | 2642 * declaration. |
2720 * | 2643 * |
2721 * @param node the throw expression expression to evaluate | 2644 * @param node the throw expression expression to evaluate |
2722 * @return `true` if and only if an error code is generated on the passed node | 2645 * @return `true` if and only if an error code is generated on the passed node |
2723 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION]. | 2646 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION]. |
2724 */ | 2647 */ |
2725 bool _checkForConstEvalThrowsException(ThrowExpression node) { | 2648 bool _checkForConstEvalThrowsException(ThrowExpression node) { |
2726 if (_isEnclosingConstructorConst) { | 2649 if (_isEnclosingConstructorConst) { |
2727 _errorReporter.reportErrorForNode( | 2650 _errorReporter.reportErrorForNode( |
2728 CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, | 2651 CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, node); |
2729 node); | |
2730 return true; | 2652 return true; |
2731 } | 2653 } |
2732 return false; | 2654 return false; |
2733 } | 2655 } |
2734 | 2656 |
2735 /** | 2657 /** |
2736 * This verifies that the passed normal formal parameter is not 'const'. | 2658 * This verifies that the passed normal formal parameter is not 'const'. |
2737 * | 2659 * |
2738 * @param node the normal formal parameter to evaluate | 2660 * @param node the normal formal parameter to evaluate |
2739 * @return `true` if and only if an error code is generated on the passed node | 2661 * @return `true` if and only if an error code is generated on the passed node |
2740 * See [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]. | 2662 * See [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]. |
2741 */ | 2663 */ |
2742 bool _checkForConstFormalParameter(NormalFormalParameter node) { | 2664 bool _checkForConstFormalParameter(NormalFormalParameter node) { |
2743 if (node.isConst) { | 2665 if (node.isConst) { |
2744 _errorReporter.reportErrorForNode( | 2666 _errorReporter.reportErrorForNode( |
2745 CompileTimeErrorCode.CONST_FORMAL_PARAMETER, | 2667 CompileTimeErrorCode.CONST_FORMAL_PARAMETER, node); |
2746 node); | |
2747 return true; | 2668 return true; |
2748 } | 2669 } |
2749 return false; | 2670 return false; |
2750 } | 2671 } |
2751 | 2672 |
2752 /** | 2673 /** |
2753 * This verifies that the passed instance creation expression is not being inv
oked on an abstract | 2674 * This verifies that the passed instance creation expression is not being inv
oked on an abstract |
2754 * class. | 2675 * class. |
2755 * | 2676 * |
2756 * @param node the instance creation expression to evaluate | 2677 * @param node the instance creation expression to evaluate |
2757 * @param typeName the [TypeName] of the [ConstructorName] from the | 2678 * @param typeName the [TypeName] of the [ConstructorName] from the |
2758 * [InstanceCreationExpression], this is the AST node that the error
is attached to | 2679 * [InstanceCreationExpression], this is the AST node that the error
is attached to |
2759 * @param type the type being constructed with this [InstanceCreationExpressio
n] | 2680 * @param type the type being constructed with this [InstanceCreationExpressio
n] |
2760 * @return `true` if and only if an error code is generated on the passed node | 2681 * @return `true` if and only if an error code is generated on the passed node |
2761 * See [StaticWarningCode.CONST_WITH_ABSTRACT_CLASS], and | 2682 * See [StaticWarningCode.CONST_WITH_ABSTRACT_CLASS], and |
2762 * [StaticWarningCode.NEW_WITH_ABSTRACT_CLASS]. | 2683 * [StaticWarningCode.NEW_WITH_ABSTRACT_CLASS]. |
2763 */ | 2684 */ |
2764 bool _checkForConstOrNewWithAbstractClass(InstanceCreationExpression node, | 2685 bool _checkForConstOrNewWithAbstractClass( |
2765 TypeName typeName, InterfaceType type) { | 2686 InstanceCreationExpression node, TypeName typeName, InterfaceType type) { |
2766 if (type.element.isAbstract) { | 2687 if (type.element.isAbstract) { |
2767 ConstructorElement element = node.staticElement; | 2688 ConstructorElement element = node.staticElement; |
2768 if (element != null && !element.isFactory) { | 2689 if (element != null && !element.isFactory) { |
2769 if ((node.keyword as sc.KeywordToken).keyword == sc.Keyword.CONST) { | 2690 if ((node.keyword as sc.KeywordToken).keyword == sc.Keyword.CONST) { |
2770 _errorReporter.reportErrorForNode( | 2691 _errorReporter.reportErrorForNode( |
2771 StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, | 2692 StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName); |
2772 typeName); | |
2773 } else { | 2693 } else { |
2774 _errorReporter.reportErrorForNode( | 2694 _errorReporter.reportErrorForNode( |
2775 StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, | 2695 StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName); |
2776 typeName); | |
2777 } | 2696 } |
2778 return true; | 2697 return true; |
2779 } | 2698 } |
2780 } | 2699 } |
2781 return false; | 2700 return false; |
2782 } | 2701 } |
2783 | 2702 |
2784 /** | 2703 /** |
2785 * This verifies that the passed instance creation expression is not being inv
oked on an enum. | 2704 * This verifies that the passed instance creation expression is not being inv
oked on an enum. |
2786 * | 2705 * |
2787 * @param node the instance creation expression to verify | 2706 * @param node the instance creation expression to verify |
2788 * @param typeName the [TypeName] of the [ConstructorName] from the | 2707 * @param typeName the [TypeName] of the [ConstructorName] from the |
2789 * [InstanceCreationExpression], this is the AST node that the error
is attached to | 2708 * [InstanceCreationExpression], this is the AST node that the error
is attached to |
2790 * @param type the type being constructed with this [InstanceCreationExpressio
n] | 2709 * @param type the type being constructed with this [InstanceCreationExpressio
n] |
2791 * @return `true` if and only if an error code is generated on the passed node | 2710 * @return `true` if and only if an error code is generated on the passed node |
2792 * See [CompileTimeErrorCode.INSTANTIATE_ENUM]. | 2711 * See [CompileTimeErrorCode.INSTANTIATE_ENUM]. |
2793 */ | 2712 */ |
2794 bool _checkForConstOrNewWithEnum(InstanceCreationExpression node, | 2713 bool _checkForConstOrNewWithEnum( |
2795 TypeName typeName, InterfaceType type) { | 2714 InstanceCreationExpression node, TypeName typeName, InterfaceType type) { |
2796 if (type.element.isEnum) { | 2715 if (type.element.isEnum) { |
2797 _errorReporter.reportErrorForNode( | 2716 _errorReporter.reportErrorForNode( |
2798 CompileTimeErrorCode.INSTANTIATE_ENUM, | 2717 CompileTimeErrorCode.INSTANTIATE_ENUM, typeName); |
2799 typeName); | |
2800 return true; | 2718 return true; |
2801 } | 2719 } |
2802 return false; | 2720 return false; |
2803 } | 2721 } |
2804 | 2722 |
2805 /** | 2723 /** |
2806 * This verifies that the passed 'const' instance creation expression is not b
eing invoked on a | 2724 * This verifies that the passed 'const' instance creation expression is not b
eing invoked on a |
2807 * constructor that is not 'const'. | 2725 * constructor that is not 'const'. |
2808 * | 2726 * |
2809 * This method assumes that the instance creation was tested to be 'const' bef
ore being called. | 2727 * This method assumes that the instance creation was tested to be 'const' bef
ore being called. |
2810 * | 2728 * |
2811 * @param node the instance creation expression to verify | 2729 * @param node the instance creation expression to verify |
2812 * @return `true` if and only if an error code is generated on the passed node | 2730 * @return `true` if and only if an error code is generated on the passed node |
2813 * See [CompileTimeErrorCode.CONST_WITH_NON_CONST]. | 2731 * See [CompileTimeErrorCode.CONST_WITH_NON_CONST]. |
2814 */ | 2732 */ |
2815 bool _checkForConstWithNonConst(InstanceCreationExpression node) { | 2733 bool _checkForConstWithNonConst(InstanceCreationExpression node) { |
2816 ConstructorElement constructorElement = node.staticElement; | 2734 ConstructorElement constructorElement = node.staticElement; |
2817 if (constructorElement != null && !constructorElement.isConst) { | 2735 if (constructorElement != null && !constructorElement.isConst) { |
2818 _errorReporter.reportErrorForNode( | 2736 _errorReporter.reportErrorForNode( |
2819 CompileTimeErrorCode.CONST_WITH_NON_CONST, | 2737 CompileTimeErrorCode.CONST_WITH_NON_CONST, node); |
2820 node); | |
2821 return true; | 2738 return true; |
2822 } | 2739 } |
2823 return false; | 2740 return false; |
2824 } | 2741 } |
2825 | 2742 |
2826 /** | 2743 /** |
2827 * This verifies that the passed type name does not reference any type paramet
ers. | 2744 * This verifies that the passed type name does not reference any type paramet
ers. |
2828 * | 2745 * |
2829 * @param typeName the type name to evaluate | 2746 * @param typeName the type name to evaluate |
2830 * @return `true` if and only if an error code is generated on the passed node | 2747 * @return `true` if and only if an error code is generated on the passed node |
2831 * See [CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS]. | 2748 * See [CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS]. |
2832 */ | 2749 */ |
2833 bool _checkForConstWithTypeParameters(TypeName typeName) { | 2750 bool _checkForConstWithTypeParameters(TypeName typeName) { |
2834 // something wrong with AST | 2751 // something wrong with AST |
2835 if (typeName == null) { | 2752 if (typeName == null) { |
2836 return false; | 2753 return false; |
2837 } | 2754 } |
2838 Identifier name = typeName.name; | 2755 Identifier name = typeName.name; |
2839 if (name == null) { | 2756 if (name == null) { |
2840 return false; | 2757 return false; |
2841 } | 2758 } |
2842 // should not be a type parameter | 2759 // should not be a type parameter |
2843 if (name.staticElement is TypeParameterElement) { | 2760 if (name.staticElement is TypeParameterElement) { |
2844 _errorReporter.reportErrorForNode( | 2761 _errorReporter.reportErrorForNode( |
2845 CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, | 2762 CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, name); |
2846 name); | |
2847 } | 2763 } |
2848 // check type arguments | 2764 // check type arguments |
2849 TypeArgumentList typeArguments = typeName.typeArguments; | 2765 TypeArgumentList typeArguments = typeName.typeArguments; |
2850 if (typeArguments != null) { | 2766 if (typeArguments != null) { |
2851 bool hasError = false; | 2767 bool hasError = false; |
2852 for (TypeName argument in typeArguments.arguments) { | 2768 for (TypeName argument in typeArguments.arguments) { |
2853 if (_checkForConstWithTypeParameters(argument)) { | 2769 if (_checkForConstWithTypeParameters(argument)) { |
2854 hasError = true; | 2770 hasError = true; |
2855 } | 2771 } |
2856 } | 2772 } |
(...skipping 28 matching lines...) Expand all Loading... |
2885 if (element != null && element.isEnum) { | 2801 if (element != null && element.isEnum) { |
2886 // We have already reported the error. | 2802 // We have already reported the error. |
2887 return false; | 2803 return false; |
2888 } | 2804 } |
2889 } | 2805 } |
2890 Identifier className = typeName.name; | 2806 Identifier className = typeName.name; |
2891 // report as named or default constructor absence | 2807 // report as named or default constructor absence |
2892 SimpleIdentifier name = constructorName.name; | 2808 SimpleIdentifier name = constructorName.name; |
2893 if (name != null) { | 2809 if (name != null) { |
2894 _errorReporter.reportErrorForNode( | 2810 _errorReporter.reportErrorForNode( |
2895 CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR, | 2811 CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR, name, [ |
2896 name, | 2812 className, |
2897 [className, name]); | 2813 name |
| 2814 ]); |
2898 } else { | 2815 } else { |
2899 _errorReporter.reportErrorForNode( | 2816 _errorReporter.reportErrorForNode( |
2900 CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, | 2817 CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, |
2901 constructorName, | 2818 constructorName, [className]); |
2902 [className]); | |
2903 } | 2819 } |
2904 return true; | 2820 return true; |
2905 } | 2821 } |
2906 | 2822 |
2907 /** | 2823 /** |
2908 * This verifies that there are no default parameters in the passed function t
ype alias. | 2824 * This verifies that there are no default parameters in the passed function t
ype alias. |
2909 * | 2825 * |
2910 * @param node the function type alias to evaluate | 2826 * @param node the function type alias to evaluate |
2911 * @return `true` if and only if an error code is generated on the passed node | 2827 * @return `true` if and only if an error code is generated on the passed node |
2912 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]. | 2828 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]. |
2913 */ | 2829 */ |
2914 bool _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) { | 2830 bool _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) { |
2915 bool result = false; | 2831 bool result = false; |
2916 FormalParameterList formalParameterList = node.parameters; | 2832 FormalParameterList formalParameterList = node.parameters; |
2917 NodeList<FormalParameter> parameters = formalParameterList.parameters; | 2833 NodeList<FormalParameter> parameters = formalParameterList.parameters; |
2918 for (FormalParameter formalParameter in parameters) { | 2834 for (FormalParameter formalParameter in parameters) { |
2919 if (formalParameter is DefaultFormalParameter) { | 2835 if (formalParameter is DefaultFormalParameter) { |
2920 DefaultFormalParameter defaultFormalParameter = formalParameter; | 2836 DefaultFormalParameter defaultFormalParameter = formalParameter; |
2921 if (defaultFormalParameter.defaultValue != null) { | 2837 if (defaultFormalParameter.defaultValue != null) { |
2922 _errorReporter.reportErrorForNode( | 2838 _errorReporter.reportErrorForNode( |
2923 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, | 2839 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, node); |
2924 node); | |
2925 result = true; | 2840 result = true; |
2926 } | 2841 } |
2927 } | 2842 } |
2928 } | 2843 } |
2929 return result; | 2844 return result; |
2930 } | 2845 } |
2931 | 2846 |
2932 /** | 2847 /** |
2933 * This verifies that the given default formal parameter is not part of a func
tion typed | 2848 * This verifies that the given default formal parameter is not part of a func
tion typed |
2934 * parameter. | 2849 * parameter. |
2935 * | 2850 * |
2936 * @param node the default formal parameter to evaluate | 2851 * @param node the default formal parameter to evaluate |
2937 * @return `true` if and only if an error code is generated on the passed node | 2852 * @return `true` if and only if an error code is generated on the passed node |
2938 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]. | 2853 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]. |
2939 */ | 2854 */ |
2940 bool | 2855 bool _checkForDefaultValueInFunctionTypedParameter( |
2941 _checkForDefaultValueInFunctionTypedParameter(DefaultFormalParameter node)
{ | 2856 DefaultFormalParameter node) { |
2942 // OK, not in a function typed parameter. | 2857 // OK, not in a function typed parameter. |
2943 if (!_isInFunctionTypedFormalParameter) { | 2858 if (!_isInFunctionTypedFormalParameter) { |
2944 return false; | 2859 return false; |
2945 } | 2860 } |
2946 // OK, no default value. | 2861 // OK, no default value. |
2947 if (node.defaultValue == null) { | 2862 if (node.defaultValue == null) { |
2948 return false; | 2863 return false; |
2949 } | 2864 } |
2950 // Report problem. | 2865 // Report problem. |
2951 _errorReporter.reportErrorForNode( | 2866 _errorReporter.reportErrorForNode( |
2952 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, | 2867 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, node); |
2953 node); | |
2954 return true; | 2868 return true; |
2955 } | 2869 } |
2956 | 2870 |
2957 /** | 2871 /** |
2958 * This verifies that any deferred imports in the given compilation unit have
a unique prefix. | 2872 * This verifies that any deferred imports in the given compilation unit have
a unique prefix. |
2959 * | 2873 * |
2960 * @param node the compilation unit containing the imports to be checked | 2874 * @param node the compilation unit containing the imports to be checked |
2961 * @return `true` if an error was generated | 2875 * @return `true` if an error was generated |
2962 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. | 2876 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. |
2963 */ | 2877 */ |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3051 String displayName; | 2965 String displayName; |
3052 Element enclosingElement = inheritedMember.enclosingElement; | 2966 Element enclosingElement = inheritedMember.enclosingElement; |
3053 if (enclosingElement.source == _enclosingClass.source) { | 2967 if (enclosingElement.source == _enclosingClass.source) { |
3054 displayName = enclosingElement.displayName; | 2968 displayName = enclosingElement.displayName; |
3055 } else { | 2969 } else { |
3056 displayName = enclosingElement.getExtendedDisplayName(null); | 2970 displayName = enclosingElement.getExtendedDisplayName(null); |
3057 } | 2971 } |
3058 // report problem | 2972 // report problem |
3059 _errorReporter.reportErrorForOffset( | 2973 _errorReporter.reportErrorForOffset( |
3060 CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE, | 2974 CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE, |
3061 staticMember.nameOffset, | 2975 staticMember.nameOffset, name.length, [name, displayName]); |
3062 name.length, | |
3063 [name, displayName]); | |
3064 return true; | 2976 return true; |
3065 } | 2977 } |
3066 | 2978 |
3067 /** | 2979 /** |
3068 * This verifies if the passed list literal has type arguments then there is e
xactly one. | 2980 * This verifies if the passed list literal has type arguments then there is e
xactly one. |
3069 * | 2981 * |
3070 * @param node the list literal to evaluate | 2982 * @param node the list literal to evaluate |
3071 * @param typeArguments the type arguments, always non-`null` | 2983 * @param typeArguments the type arguments, always non-`null` |
3072 * @return `true` if and only if an error code is generated on the passed node | 2984 * @return `true` if and only if an error code is generated on the passed node |
3073 * See [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS]. | 2985 * See [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS]. |
3074 */ | 2986 */ |
3075 bool _checkForExpectedOneListTypeArgument(ListLiteral node, | 2987 bool _checkForExpectedOneListTypeArgument( |
3076 TypeArgumentList typeArguments) { | 2988 ListLiteral node, TypeArgumentList typeArguments) { |
3077 // check number of type arguments | 2989 // check number of type arguments |
3078 int num = typeArguments.arguments.length; | 2990 int num = typeArguments.arguments.length; |
3079 if (num == 1) { | 2991 if (num == 1) { |
3080 return false; | 2992 return false; |
3081 } | 2993 } |
3082 // report problem | 2994 // report problem |
3083 _errorReporter.reportErrorForNode( | 2995 _errorReporter.reportErrorForNode( |
3084 StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, | 2996 StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments, [ |
3085 typeArguments, | 2997 num |
3086 [num]); | 2998 ]); |
3087 return true; | 2999 return true; |
3088 } | 3000 } |
3089 | 3001 |
3090 /** | 3002 /** |
3091 * This verifies the passed import has unique name among other exported librar
ies. | 3003 * This verifies the passed import has unique name among other exported librar
ies. |
3092 * | 3004 * |
3093 * @param node the export directive to evaluate | 3005 * @param node the export directive to evaluate |
3094 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the | 3006 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the |
3095 * node was `null`, then this method is not called | 3007 * node was `null`, then this method is not called |
3096 * @param exportedLibrary the library element containing the exported element | 3008 * @param exportedLibrary the library element containing the exported element |
3097 * @return `true` if and only if an error code is generated on the passed node | 3009 * @return `true` if and only if an error code is generated on the passed node |
3098 * See [CompileTimeErrorCode.EXPORT_DUPLICATED_LIBRARY_NAME]. | 3010 * See [CompileTimeErrorCode.EXPORT_DUPLICATED_LIBRARY_NAME]. |
3099 */ | 3011 */ |
3100 bool _checkForExportDuplicateLibraryName(ExportDirective node, | 3012 bool _checkForExportDuplicateLibraryName(ExportDirective node, |
3101 ExportElement exportElement, LibraryElement exportedLibrary) { | 3013 ExportElement exportElement, LibraryElement exportedLibrary) { |
3102 if (exportedLibrary == null) { | 3014 if (exportedLibrary == null) { |
3103 return false; | 3015 return false; |
3104 } | 3016 } |
3105 String name = exportedLibrary.name; | 3017 String name = exportedLibrary.name; |
3106 // check if there is other exported library with the same name | 3018 // check if there is other exported library with the same name |
3107 LibraryElement prevLibrary = _nameToExportElement[name]; | 3019 LibraryElement prevLibrary = _nameToExportElement[name]; |
3108 if (prevLibrary != null) { | 3020 if (prevLibrary != null) { |
3109 if (prevLibrary != exportedLibrary) { | 3021 if (prevLibrary != exportedLibrary) { |
3110 if (name.isEmpty) { | 3022 if (name.isEmpty) { |
3111 _errorReporter.reportErrorForNode( | 3023 _errorReporter.reportErrorForNode( |
3112 StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_UNNAMED, | 3024 StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_UNNAMED, node, [ |
3113 node, | 3025 prevLibrary.definingCompilationUnit.displayName, |
3114 [ | 3026 exportedLibrary.definingCompilationUnit.displayName |
3115 prevLibrary.definingCompilationUnit.displayName, | 3027 ]); |
3116 exportedLibrary.definingCompilationUnit.displayName]); | |
3117 } else { | 3028 } else { |
3118 _errorReporter.reportErrorForNode( | 3029 _errorReporter.reportErrorForNode( |
3119 StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAMED, | 3030 StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAMED, node, [ |
3120 node, | 3031 prevLibrary.definingCompilationUnit.displayName, |
3121 [ | 3032 exportedLibrary.definingCompilationUnit.displayName, |
3122 prevLibrary.definingCompilationUnit.displayName, | 3033 name |
3123 exportedLibrary.definingCompilationUnit.displayName, | 3034 ]); |
3124 name]); | |
3125 } | 3035 } |
3126 return true; | 3036 return true; |
3127 } | 3037 } |
3128 } else { | 3038 } else { |
3129 _nameToExportElement[name] = exportedLibrary; | 3039 _nameToExportElement[name] = exportedLibrary; |
3130 } | 3040 } |
3131 // OK | 3041 // OK |
3132 return false; | 3042 return false; |
3133 } | 3043 } |
3134 | 3044 |
3135 /** | 3045 /** |
3136 * Check that if the visiting library is not system, then any passed library s
hould not be SDK | 3046 * Check that if the visiting library is not system, then any passed library s
hould not be SDK |
3137 * internal library. | 3047 * internal library. |
3138 * | 3048 * |
3139 * @param node the export directive to evaluate | 3049 * @param node the export directive to evaluate |
3140 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the | 3050 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the |
3141 * node was `null`, then this method is not called | 3051 * node was `null`, then this method is not called |
3142 * @return `true` if and only if an error code is generated on the passed node | 3052 * @return `true` if and only if an error code is generated on the passed node |
3143 * See [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY]. | 3053 * See [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY]. |
3144 */ | 3054 */ |
3145 bool _checkForExportInternalLibrary(ExportDirective node, | 3055 bool _checkForExportInternalLibrary( |
3146 ExportElement exportElement) { | 3056 ExportDirective node, ExportElement exportElement) { |
3147 if (_isInSystemLibrary) { | 3057 if (_isInSystemLibrary) { |
3148 return false; | 3058 return false; |
3149 } | 3059 } |
3150 // should be private | 3060 // should be private |
3151 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; | 3061 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; |
3152 String uri = exportElement.uri; | 3062 String uri = exportElement.uri; |
3153 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); | 3063 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); |
3154 if (sdkLibrary == null) { | 3064 if (sdkLibrary == null) { |
3155 return false; | 3065 return false; |
3156 } | 3066 } |
3157 if (!sdkLibrary.isInternal) { | 3067 if (!sdkLibrary.isInternal) { |
3158 return false; | 3068 return false; |
3159 } | 3069 } |
3160 // report problem | 3070 // report problem |
3161 _errorReporter.reportErrorForNode( | 3071 _errorReporter.reportErrorForNode( |
3162 CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, | 3072 CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, node, [node.uri]); |
3163 node, | |
3164 [node.uri]); | |
3165 return true; | 3073 return true; |
3166 } | 3074 } |
3167 | 3075 |
3168 /** | 3076 /** |
3169 * This verifies that the passed extends clause does not extend a deferred cla
ss. | 3077 * This verifies that the passed extends clause does not extend a deferred cla
ss. |
3170 * | 3078 * |
3171 * @param node the extends clause to test | 3079 * @param node the extends clause to test |
3172 * @return `true` if and only if an error code is generated on the passed node | 3080 * @return `true` if and only if an error code is generated on the passed node |
3173 * See [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS]. | 3081 * See [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS]. |
3174 */ | 3082 */ |
3175 bool _checkForExtendsDeferredClass(ExtendsClause node) { | 3083 bool _checkForExtendsDeferredClass(ExtendsClause node) { |
3176 if (node == null) { | 3084 if (node == null) { |
3177 return false; | 3085 return false; |
3178 } | 3086 } |
3179 return _checkForExtendsOrImplementsDeferredClass( | 3087 return _checkForExtendsOrImplementsDeferredClass( |
3180 node.superclass, | 3088 node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); |
3181 CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); | |
3182 } | 3089 } |
3183 | 3090 |
3184 /** | 3091 /** |
3185 * This verifies that the passed type alias does not extend a deferred class. | 3092 * This verifies that the passed type alias does not extend a deferred class. |
3186 * | 3093 * |
3187 * @param node the extends clause to test | 3094 * @param node the extends clause to test |
3188 * @return `true` if and only if an error code is generated on the passed node | 3095 * @return `true` if and only if an error code is generated on the passed node |
3189 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. | 3096 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. |
3190 */ | 3097 */ |
3191 bool _checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias node) { | 3098 bool _checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias node) { |
3192 if (node == null) { | 3099 if (node == null) { |
3193 return false; | 3100 return false; |
3194 } | 3101 } |
3195 return _checkForExtendsOrImplementsDeferredClass( | 3102 return _checkForExtendsOrImplementsDeferredClass( |
3196 node.superclass, | 3103 node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); |
3197 CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); | |
3198 } | 3104 } |
3199 | 3105 |
3200 /** | 3106 /** |
3201 * This verifies that the passed extends clause does not extend classes such a
s num or String. | 3107 * This verifies that the passed extends clause does not extend classes such a
s num or String. |
3202 * | 3108 * |
3203 * @param node the extends clause to test | 3109 * @param node the extends clause to test |
3204 * @return `true` if and only if an error code is generated on the passed node | 3110 * @return `true` if and only if an error code is generated on the passed node |
3205 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. | 3111 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. |
3206 */ | 3112 */ |
3207 bool _checkForExtendsDisallowedClass(ExtendsClause node) { | 3113 bool _checkForExtendsDisallowedClass(ExtendsClause node) { |
3208 if (node == null) { | 3114 if (node == null) { |
3209 return false; | 3115 return false; |
3210 } | 3116 } |
3211 return _checkForExtendsOrImplementsDisallowedClass( | 3117 return _checkForExtendsOrImplementsDisallowedClass( |
3212 node.superclass, | 3118 node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); |
3213 CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); | |
3214 } | 3119 } |
3215 | 3120 |
3216 /** | 3121 /** |
3217 * This verifies that the passed type alias does not extend classes such as nu
m or String. | 3122 * This verifies that the passed type alias does not extend classes such as nu
m or String. |
3218 * | 3123 * |
3219 * @param node the extends clause to test | 3124 * @param node the extends clause to test |
3220 * @return `true` if and only if an error code is generated on the passed node | 3125 * @return `true` if and only if an error code is generated on the passed node |
3221 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. | 3126 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. |
3222 */ | 3127 */ |
3223 bool _checkForExtendsDisallowedClassInTypeAlias(ClassTypeAlias node) { | 3128 bool _checkForExtendsDisallowedClassInTypeAlias(ClassTypeAlias node) { |
3224 if (node == null) { | 3129 if (node == null) { |
3225 return false; | 3130 return false; |
3226 } | 3131 } |
3227 return _checkForExtendsOrImplementsDisallowedClass( | 3132 return _checkForExtendsOrImplementsDisallowedClass( |
3228 node.superclass, | 3133 node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); |
3229 CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); | |
3230 } | 3134 } |
3231 | 3135 |
3232 /** | 3136 /** |
3233 * This verifies that the passed type name does not extend, implement or mixin
classes that are | 3137 * This verifies that the passed type name does not extend, implement or mixin
classes that are |
3234 * deferred. | 3138 * deferred. |
3235 * | 3139 * |
3236 * @param node the type name to test | 3140 * @param node the type name to test |
3237 * @return `true` if and only if an error code is generated on the passed node | 3141 * @return `true` if and only if an error code is generated on the passed node |
3238 * See [_checkForExtendsDeferredClass], | 3142 * See [_checkForExtendsDeferredClass], |
3239 * [_checkForExtendsDeferredClassInTypeAlias], | 3143 * [_checkForExtendsDeferredClassInTypeAlias], |
3240 * [_checkForImplementsDeferredClass], | 3144 * [_checkForImplementsDeferredClass], |
3241 * [_checkForAllMixinErrorCodes], | 3145 * [_checkForAllMixinErrorCodes], |
3242 * [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS], | 3146 * [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS], |
3243 * [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS], and | 3147 * [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS], and |
3244 * [CompileTimeErrorCode.MIXIN_DEFERRED_CLASS]. | 3148 * [CompileTimeErrorCode.MIXIN_DEFERRED_CLASS]. |
3245 */ | 3149 */ |
3246 bool _checkForExtendsOrImplementsDeferredClass(TypeName typeName, | 3150 bool _checkForExtendsOrImplementsDeferredClass( |
3247 ErrorCode errorCode) { | 3151 TypeName typeName, ErrorCode errorCode) { |
3248 if (typeName.isSynthetic) { | 3152 if (typeName.isSynthetic) { |
3249 return false; | 3153 return false; |
3250 } | 3154 } |
3251 if (typeName.isDeferred) { | 3155 if (typeName.isDeferred) { |
3252 _errorReporter.reportErrorForNode( | 3156 _errorReporter.reportErrorForNode( |
3253 errorCode, | 3157 errorCode, typeName, [typeName.name.name]); |
3254 typeName, | |
3255 [typeName.name.name]); | |
3256 return true; | 3158 return true; |
3257 } | 3159 } |
3258 return false; | 3160 return false; |
3259 } | 3161 } |
3260 | 3162 |
3261 /** | 3163 /** |
3262 * This verifies that the passed type name does not extend, implement or mixin
classes such as | 3164 * This verifies that the passed type name does not extend, implement or mixin
classes such as |
3263 * 'num' or 'String'. | 3165 * 'num' or 'String'. |
3264 * | 3166 * |
3265 * @param node the type name to test | 3167 * @param node the type name to test |
3266 * @return `true` if and only if an error code is generated on the passed node | 3168 * @return `true` if and only if an error code is generated on the passed node |
3267 * See [_checkForExtendsDisallowedClass], | 3169 * See [_checkForExtendsDisallowedClass], |
3268 * [_checkForExtendsDisallowedClassInTypeAlias], | 3170 * [_checkForExtendsDisallowedClassInTypeAlias], |
3269 * [_checkForImplementsDisallowedClass], | 3171 * [_checkForImplementsDisallowedClass], |
3270 * [_checkForAllMixinErrorCodes], | 3172 * [_checkForAllMixinErrorCodes], |
3271 * [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS], | 3173 * [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS], |
3272 * [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS], and | 3174 * [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS], and |
3273 * [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]. | 3175 * [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]. |
3274 */ | 3176 */ |
3275 bool _checkForExtendsOrImplementsDisallowedClass(TypeName typeName, | 3177 bool _checkForExtendsOrImplementsDisallowedClass( |
3276 ErrorCode errorCode) { | 3178 TypeName typeName, ErrorCode errorCode) { |
3277 if (typeName.isSynthetic) { | 3179 if (typeName.isSynthetic) { |
3278 return false; | 3180 return false; |
3279 } | 3181 } |
3280 DartType superType = typeName.type; | 3182 DartType superType = typeName.type; |
3281 for (InterfaceType disallowedType in | 3183 for (InterfaceType disallowedType |
3282 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT) { | 3184 in _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT) { |
3283 if (superType != null && superType == disallowedType) { | 3185 if (superType != null && superType == disallowedType) { |
3284 // if the violating type happens to be 'num', we need to rule out the | 3186 // if the violating type happens to be 'num', we need to rule out the |
3285 // case where the enclosing class is 'int' or 'double' | 3187 // case where the enclosing class is 'int' or 'double' |
3286 if (superType == _typeProvider.numType) { | 3188 if (superType == _typeProvider.numType) { |
3287 AstNode grandParent = typeName.parent.parent; | 3189 AstNode grandParent = typeName.parent.parent; |
3288 // Note: this is a corner case that won't happen often, so adding a | 3190 // Note: this is a corner case that won't happen often, so adding a |
3289 // field currentClass (see currentFunction) to ErrorVerifier isn't | 3191 // field currentClass (see currentFunction) to ErrorVerifier isn't |
3290 // worth if for this case, but if the field currentClass is added, | 3192 // worth if for this case, but if the field currentClass is added, |
3291 // then this message should become a todo to not lookup the | 3193 // then this message should become a todo to not lookup the |
3292 // grandparent node. | 3194 // grandparent node. |
3293 if (grandParent is ClassDeclaration) { | 3195 if (grandParent is ClassDeclaration) { |
3294 ClassElement classElement = grandParent.element; | 3196 ClassElement classElement = grandParent.element; |
3295 DartType classType = classElement.type; | 3197 DartType classType = classElement.type; |
3296 if (classType != null && | 3198 if (classType != null && |
3297 (classType == _intType || classType == _typeProvider.doubleType)
) { | 3199 (classType == _intType || |
| 3200 classType == _typeProvider.doubleType)) { |
3298 return false; | 3201 return false; |
3299 } | 3202 } |
3300 } | 3203 } |
3301 } | 3204 } |
3302 // otherwise, report the error | 3205 // otherwise, report the error |
3303 _errorReporter.reportErrorForNode( | 3206 _errorReporter.reportErrorForNode( |
3304 errorCode, | 3207 errorCode, typeName, [disallowedType.displayName]); |
3305 typeName, | |
3306 [disallowedType.displayName]); | |
3307 return true; | 3208 return true; |
3308 } | 3209 } |
3309 } | 3210 } |
3310 return false; | 3211 return false; |
3311 } | 3212 } |
3312 | 3213 |
3313 /** | 3214 /** |
3314 * This verifies that the passed constructor field initializer has compatible
field and | 3215 * This verifies that the passed constructor field initializer has compatible
field and |
3315 * initializer expression types. | 3216 * initializer expression types. |
3316 * | 3217 * |
3317 * @param node the constructor field initializer to test | 3218 * @param node the constructor field initializer to test |
3318 * @param staticElement the static element from the name in the | 3219 * @param staticElement the static element from the name in the |
3319 * [ConstructorFieldInitializer] | 3220 * [ConstructorFieldInitializer] |
3320 * @return `true` if and only if an error code is generated on the passed node | 3221 * @return `true` if and only if an error code is generated on the passed node |
3321 * See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and | 3222 * See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and |
3322 * [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE]. | 3223 * [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE]. |
3323 */ | 3224 */ |
3324 bool _checkForFieldInitializerNotAssignable(ConstructorFieldInitializer node, | 3225 bool _checkForFieldInitializerNotAssignable( |
3325 Element staticElement) { | 3226 ConstructorFieldInitializer node, Element staticElement) { |
3326 // prepare field element | 3227 // prepare field element |
3327 if (staticElement is! FieldElement) { | 3228 if (staticElement is! FieldElement) { |
3328 return false; | 3229 return false; |
3329 } | 3230 } |
3330 FieldElement fieldElement = staticElement as FieldElement; | 3231 FieldElement fieldElement = staticElement as FieldElement; |
3331 // prepare field type | 3232 // prepare field type |
3332 DartType fieldType = fieldElement.type; | 3233 DartType fieldType = fieldElement.type; |
3333 // prepare expression type | 3234 // prepare expression type |
3334 Expression expression = node.expression; | 3235 Expression expression = node.expression; |
3335 if (expression == null) { | 3236 if (expression == null) { |
3336 return false; | 3237 return false; |
3337 } | 3238 } |
3338 // test the static type of the expression | 3239 // test the static type of the expression |
3339 DartType staticType = getStaticType(expression); | 3240 DartType staticType = getStaticType(expression); |
3340 if (staticType == null) { | 3241 if (staticType == null) { |
3341 return false; | 3242 return false; |
3342 } | 3243 } |
3343 if (staticType.isAssignableTo(fieldType)) { | 3244 if (staticType.isAssignableTo(fieldType)) { |
3344 return false; | 3245 return false; |
3345 } | 3246 } |
3346 // report problem | 3247 // report problem |
3347 if (_isEnclosingConstructorConst) { | 3248 if (_isEnclosingConstructorConst) { |
3348 // TODO(paulberry): this error should be based on the actual type of the | 3249 // TODO(paulberry): this error should be based on the actual type of the |
3349 // constant, not the static type. See dartbug.com/21119. | 3250 // constant, not the static type. See dartbug.com/21119. |
3350 _errorReporter.reportTypeErrorForNode( | 3251 _errorReporter.reportTypeErrorForNode( |
3351 CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
, | 3252 CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
, |
3352 expression, | 3253 expression, [staticType, fieldType]); |
3353 [staticType, fieldType]); | |
3354 } | 3254 } |
3355 _errorReporter.reportTypeErrorForNode( | 3255 _errorReporter.reportTypeErrorForNode( |
3356 StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, | 3256 StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, expression, [ |
3357 expression, | 3257 staticType, |
3358 [staticType, fieldType]); | 3258 fieldType |
| 3259 ]); |
3359 return true; | 3260 return true; |
3360 // TODO(brianwilkerson) Define a hint corresponding to these errors and | 3261 // TODO(brianwilkerson) Define a hint corresponding to these errors and |
3361 // report it if appropriate. | 3262 // report it if appropriate. |
3362 // // test the propagated type of the expression | 3263 // // test the propagated type of the expression |
3363 // Type propagatedType = expression.getPropagatedType(); | 3264 // Type propagatedType = expression.getPropagatedType(); |
3364 // if (propagatedType != null && propagatedType.isAssignableTo(fieldType)
) { | 3265 // if (propagatedType != null && propagatedType.isAssignableTo(fieldType)
) { |
3365 // return false; | 3266 // return false; |
3366 // } | 3267 // } |
3367 // // report problem | 3268 // // report problem |
3368 // if (isEnclosingConstructorConst) { | 3269 // if (isEnclosingConstructorConst) { |
(...skipping 12 matching lines...) Expand all Loading... |
3381 // return true; | 3282 // return true; |
3382 } | 3283 } |
3383 | 3284 |
3384 /** | 3285 /** |
3385 * This verifies that the passed field formal parameter is in a constructor de
claration. | 3286 * This verifies that the passed field formal parameter is in a constructor de
claration. |
3386 * | 3287 * |
3387 * @param node the field formal parameter to test | 3288 * @param node the field formal parameter to test |
3388 * @return `true` if and only if an error code is generated on the passed node | 3289 * @return `true` if and only if an error code is generated on the passed node |
3389 * See [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]. | 3290 * See [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]. |
3390 */ | 3291 */ |
3391 bool | 3292 bool _checkForFieldInitializingFormalRedirectingConstructor( |
3392 _checkForFieldInitializingFormalRedirectingConstructor(FieldFormalParamete
r node) { | 3293 FieldFormalParameter node) { |
3393 ConstructorDeclaration constructor = | 3294 ConstructorDeclaration constructor = |
3394 node.getAncestor((node) => node is ConstructorDeclaration); | 3295 node.getAncestor((node) => node is ConstructorDeclaration); |
3395 if (constructor == null) { | 3296 if (constructor == null) { |
3396 _errorReporter.reportErrorForNode( | 3297 _errorReporter.reportErrorForNode( |
3397 CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, | 3298 CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, node); |
3398 node); | |
3399 return true; | 3299 return true; |
3400 } | 3300 } |
3401 // constructor cannot be a factory | 3301 // constructor cannot be a factory |
3402 if (constructor.factoryKeyword != null) { | 3302 if (constructor.factoryKeyword != null) { |
3403 _errorReporter.reportErrorForNode( | 3303 _errorReporter.reportErrorForNode( |
3404 CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, | 3304 CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, node); |
3405 node); | |
3406 return true; | 3305 return true; |
3407 } | 3306 } |
3408 // constructor cannot have a redirection | 3307 // constructor cannot have a redirection |
3409 for (ConstructorInitializer initializer in constructor.initializers) { | 3308 for (ConstructorInitializer initializer in constructor.initializers) { |
3410 if (initializer is RedirectingConstructorInvocation) { | 3309 if (initializer is RedirectingConstructorInvocation) { |
3411 _errorReporter.reportErrorForNode( | 3310 _errorReporter.reportErrorForNode( |
3412 CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, | 3311 CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, |
3413 node); | 3312 node); |
3414 return true; | 3313 return true; |
3415 } | 3314 } |
(...skipping 18 matching lines...) Expand all Loading... |
3434 if (_isInNativeClass) { | 3333 if (_isInNativeClass) { |
3435 return false; | 3334 return false; |
3436 } | 3335 } |
3437 bool foundError = false; | 3336 bool foundError = false; |
3438 if (!node.isSynthetic) { | 3337 if (!node.isSynthetic) { |
3439 NodeList<VariableDeclaration> variables = node.variables; | 3338 NodeList<VariableDeclaration> variables = node.variables; |
3440 for (VariableDeclaration variable in variables) { | 3339 for (VariableDeclaration variable in variables) { |
3441 if (variable.initializer == null) { | 3340 if (variable.initializer == null) { |
3442 if (node.isConst) { | 3341 if (node.isConst) { |
3443 _errorReporter.reportErrorForNode( | 3342 _errorReporter.reportErrorForNode( |
3444 CompileTimeErrorCode.CONST_NOT_INITIALIZED, | 3343 CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, [ |
3445 variable.name, | 3344 variable.name.name |
3446 [variable.name.name]); | 3345 ]); |
3447 } else if (node.isFinal) { | 3346 } else if (node.isFinal) { |
3448 _errorReporter.reportErrorForNode( | 3347 _errorReporter.reportErrorForNode( |
3449 StaticWarningCode.FINAL_NOT_INITIALIZED, | 3348 StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, [ |
3450 variable.name, | 3349 variable.name.name |
3451 [variable.name.name]); | 3350 ]); |
3452 } | 3351 } |
3453 foundError = true; | 3352 foundError = true; |
3454 } | 3353 } |
3455 } | 3354 } |
3456 } | 3355 } |
3457 return foundError; | 3356 return foundError; |
3458 } | 3357 } |
3459 | 3358 |
3460 /** | 3359 /** |
3461 * This verifies that final fields that are declared, without any constructors
in the enclosing | 3360 * This verifies that final fields that are declared, without any constructors
in the enclosing |
(...skipping 28 matching lines...) Expand all Loading... |
3490 * respectively. If not, report the error using [node]. | 3389 * respectively. If not, report the error using [node]. |
3491 */ | 3390 */ |
3492 void _checkForIllegalReturnType(TypeName node) { | 3391 void _checkForIllegalReturnType(TypeName node) { |
3493 if (node == null) { | 3392 if (node == null) { |
3494 // No declared return type, so the return type must be dynamic, which is | 3393 // No declared return type, so the return type must be dynamic, which is |
3495 // assignable to everything. | 3394 // assignable to everything. |
3496 return; | 3395 return; |
3497 } | 3396 } |
3498 if (_enclosingFunction.isAsynchronous) { | 3397 if (_enclosingFunction.isAsynchronous) { |
3499 if (_enclosingFunction.isGenerator) { | 3398 if (_enclosingFunction.isGenerator) { |
3500 if (!_enclosingFunction.returnType.isAssignableTo( | 3399 if (!_enclosingFunction.returnType |
3501 _typeProvider.streamDynamicType)) { | 3400 .isAssignableTo(_typeProvider.streamDynamicType)) { |
3502 _errorReporter.reportErrorForNode( | 3401 _errorReporter.reportErrorForNode( |
3503 StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE, | 3402 StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE, node); |
3504 node); | |
3505 } | 3403 } |
3506 } else { | 3404 } else { |
3507 if (!_enclosingFunction.returnType.isAssignableTo( | 3405 if (!_enclosingFunction.returnType |
3508 _typeProvider.futureDynamicType)) { | 3406 .isAssignableTo(_typeProvider.futureDynamicType)) { |
3509 _errorReporter.reportErrorForNode( | 3407 _errorReporter.reportErrorForNode( |
3510 StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, | 3408 StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, node); |
3511 node); | |
3512 } | 3409 } |
3513 } | 3410 } |
3514 } else if (_enclosingFunction.isGenerator) { | 3411 } else if (_enclosingFunction.isGenerator) { |
3515 if (!_enclosingFunction.returnType.isAssignableTo( | 3412 if (!_enclosingFunction.returnType |
3516 _typeProvider.iterableDynamicType)) { | 3413 .isAssignableTo(_typeProvider.iterableDynamicType)) { |
3517 _errorReporter.reportErrorForNode( | 3414 _errorReporter.reportErrorForNode( |
3518 StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, | 3415 StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, node); |
3519 node); | |
3520 } | 3416 } |
3521 } | 3417 } |
3522 } | 3418 } |
3523 | 3419 |
3524 /** | 3420 /** |
3525 * This verifies that the passed implements clause does not implement classes
that are deferred. | 3421 * This verifies that the passed implements clause does not implement classes
that are deferred. |
3526 * | 3422 * |
3527 * @param node the implements clause to test | 3423 * @param node the implements clause to test |
3528 * @return `true` if and only if an error code is generated on the passed node | 3424 * @return `true` if and only if an error code is generated on the passed node |
3529 * See [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS]. | 3425 * See [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS]. |
3530 */ | 3426 */ |
3531 bool _checkForImplementsDeferredClass(ImplementsClause node) { | 3427 bool _checkForImplementsDeferredClass(ImplementsClause node) { |
3532 if (node == null) { | 3428 if (node == null) { |
3533 return false; | 3429 return false; |
3534 } | 3430 } |
3535 bool foundError = false; | 3431 bool foundError = false; |
3536 for (TypeName type in node.interfaces) { | 3432 for (TypeName type in node.interfaces) { |
3537 if (_checkForExtendsOrImplementsDeferredClass( | 3433 if (_checkForExtendsOrImplementsDeferredClass( |
3538 type, | 3434 type, CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS)) { |
3539 CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS)) { | |
3540 foundError = true; | 3435 foundError = true; |
3541 } | 3436 } |
3542 } | 3437 } |
3543 return foundError; | 3438 return foundError; |
3544 } | 3439 } |
3545 | 3440 |
3546 /** | 3441 /** |
3547 * This verifies that the passed implements clause does not implement classes
such as 'num' or | 3442 * This verifies that the passed implements clause does not implement classes
such as 'num' or |
3548 * 'String'. | 3443 * 'String'. |
3549 * | 3444 * |
3550 * @param node the implements clause to test | 3445 * @param node the implements clause to test |
3551 * @return `true` if and only if an error code is generated on the passed node | 3446 * @return `true` if and only if an error code is generated on the passed node |
3552 * See [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]. | 3447 * See [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]. |
3553 */ | 3448 */ |
3554 bool _checkForImplementsDisallowedClass(ImplementsClause node) { | 3449 bool _checkForImplementsDisallowedClass(ImplementsClause node) { |
3555 if (node == null) { | 3450 if (node == null) { |
3556 return false; | 3451 return false; |
3557 } | 3452 } |
3558 bool foundError = false; | 3453 bool foundError = false; |
3559 for (TypeName type in node.interfaces) { | 3454 for (TypeName type in node.interfaces) { |
3560 if (_checkForExtendsOrImplementsDisallowedClass( | 3455 if (_checkForExtendsOrImplementsDisallowedClass( |
3561 type, | 3456 type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) { |
3562 CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) { | |
3563 foundError = true; | 3457 foundError = true; |
3564 } | 3458 } |
3565 } | 3459 } |
3566 return foundError; | 3460 return foundError; |
3567 } | 3461 } |
3568 | 3462 |
3569 /** | 3463 /** |
3570 * This verifies that if the passed identifier is part of constructor initiali
zer, then it does | 3464 * This verifies that if the passed identifier is part of constructor initiali
zer, then it does |
3571 * not reference implicitly 'this' expression. | 3465 * not reference implicitly 'this' expression. |
3572 * | 3466 * |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3621 } | 3515 } |
3622 if (parent is PrefixedIdentifier) { | 3516 if (parent is PrefixedIdentifier) { |
3623 PrefixedIdentifier prefixed = parent; | 3517 PrefixedIdentifier prefixed = parent; |
3624 if (identical(prefixed.identifier, node)) { | 3518 if (identical(prefixed.identifier, node)) { |
3625 return false; | 3519 return false; |
3626 } | 3520 } |
3627 } | 3521 } |
3628 // report problem | 3522 // report problem |
3629 if (_isInStaticMethod) { | 3523 if (_isInStaticMethod) { |
3630 _errorReporter.reportErrorForNode( | 3524 _errorReporter.reportErrorForNode( |
3631 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, | 3525 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, node); |
3632 node); | |
3633 } else if (_isInFactory) { | 3526 } else if (_isInFactory) { |
3634 _errorReporter.reportErrorForNode( | 3527 _errorReporter.reportErrorForNode( |
3635 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, | 3528 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, node); |
3636 node); | |
3637 } else { | 3529 } else { |
3638 _errorReporter.reportErrorForNode( | 3530 _errorReporter.reportErrorForNode( |
3639 CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, | 3531 CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, node); |
3640 node); | |
3641 } | 3532 } |
3642 return true; | 3533 return true; |
3643 } | 3534 } |
3644 | 3535 |
3645 /** | 3536 /** |
3646 * This verifies the passed import has unique name among other imported librar
ies. | 3537 * This verifies the passed import has unique name among other imported librar
ies. |
3647 * | 3538 * |
3648 * @param node the import directive to evaluate | 3539 * @param node the import directive to evaluate |
3649 * @param importElement the [ImportElement] retrieved from the node, if the el
ement in the | 3540 * @param importElement the [ImportElement] retrieved from the node, if the el
ement in the |
3650 * node was `null`, then this method is not called | 3541 * node was `null`, then this method is not called |
3651 * @return `true` if and only if an error code is generated on the passed node | 3542 * @return `true` if and only if an error code is generated on the passed node |
3652 * See [CompileTimeErrorCode.IMPORT_DUPLICATED_LIBRARY_NAME]. | 3543 * See [CompileTimeErrorCode.IMPORT_DUPLICATED_LIBRARY_NAME]. |
3653 */ | 3544 */ |
3654 bool _checkForImportDuplicateLibraryName(ImportDirective node, | 3545 bool _checkForImportDuplicateLibraryName( |
3655 ImportElement importElement) { | 3546 ImportDirective node, ImportElement importElement) { |
3656 // prepare imported library | 3547 // prepare imported library |
3657 LibraryElement nodeLibrary = importElement.importedLibrary; | 3548 LibraryElement nodeLibrary = importElement.importedLibrary; |
3658 if (nodeLibrary == null) { | 3549 if (nodeLibrary == null) { |
3659 return false; | 3550 return false; |
3660 } | 3551 } |
3661 String name = nodeLibrary.name; | 3552 String name = nodeLibrary.name; |
3662 // check if there is another imported library with the same name | 3553 // check if there is another imported library with the same name |
3663 LibraryElement prevLibrary = _nameToImportElement[name]; | 3554 LibraryElement prevLibrary = _nameToImportElement[name]; |
3664 if (prevLibrary != null) { | 3555 if (prevLibrary != null) { |
3665 if (prevLibrary != nodeLibrary) { | 3556 if (prevLibrary != nodeLibrary) { |
3666 if (name.isEmpty) { | 3557 if (name.isEmpty) { |
3667 _errorReporter.reportErrorForNode( | 3558 _errorReporter.reportErrorForNode( |
3668 StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_UNNAMED, | 3559 StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_UNNAMED, node, [ |
3669 node, | 3560 prevLibrary.definingCompilationUnit.displayName, |
3670 [ | 3561 nodeLibrary.definingCompilationUnit.displayName |
3671 prevLibrary.definingCompilationUnit.displayName, | 3562 ]); |
3672 nodeLibrary.definingCompilationUnit.displayName]); | |
3673 } else { | 3563 } else { |
3674 _errorReporter.reportErrorForNode( | 3564 _errorReporter.reportErrorForNode( |
3675 StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAMED, | 3565 StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAMED, node, [ |
3676 node, | 3566 prevLibrary.definingCompilationUnit.displayName, |
3677 [ | 3567 nodeLibrary.definingCompilationUnit.displayName, |
3678 prevLibrary.definingCompilationUnit.displayName, | 3568 name |
3679 nodeLibrary.definingCompilationUnit.displayName, | 3569 ]); |
3680 name]); | |
3681 } | 3570 } |
3682 return true; | 3571 return true; |
3683 } | 3572 } |
3684 } else { | 3573 } else { |
3685 _nameToImportElement[name] = nodeLibrary; | 3574 _nameToImportElement[name] = nodeLibrary; |
3686 } | 3575 } |
3687 // OK | 3576 // OK |
3688 return false; | 3577 return false; |
3689 } | 3578 } |
3690 | 3579 |
3691 /** | 3580 /** |
3692 * Check that if the visiting library is not system, then any passed library s
hould not be SDK | 3581 * Check that if the visiting library is not system, then any passed library s
hould not be SDK |
3693 * internal library. | 3582 * internal library. |
3694 * | 3583 * |
3695 * @param node the import directive to evaluate | 3584 * @param node the import directive to evaluate |
3696 * @param importElement the [ImportElement] retrieved from the node, if the el
ement in the | 3585 * @param importElement the [ImportElement] retrieved from the node, if the el
ement in the |
3697 * node was `null`, then this method is not called | 3586 * node was `null`, then this method is not called |
3698 * @return `true` if and only if an error code is generated on the passed node | 3587 * @return `true` if and only if an error code is generated on the passed node |
3699 * See [CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY]. | 3588 * See [CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY]. |
3700 */ | 3589 */ |
3701 bool _checkForImportInternalLibrary(ImportDirective node, | 3590 bool _checkForImportInternalLibrary( |
3702 ImportElement importElement) { | 3591 ImportDirective node, ImportElement importElement) { |
3703 if (_isInSystemLibrary) { | 3592 if (_isInSystemLibrary) { |
3704 return false; | 3593 return false; |
3705 } | 3594 } |
3706 // should be private | 3595 // should be private |
3707 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; | 3596 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; |
3708 String uri = importElement.uri; | 3597 String uri = importElement.uri; |
3709 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); | 3598 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); |
3710 if (sdkLibrary == null) { | 3599 if (sdkLibrary == null) { |
3711 return false; | 3600 return false; |
3712 } | 3601 } |
3713 if (!sdkLibrary.isInternal) { | 3602 if (!sdkLibrary.isInternal) { |
3714 return false; | 3603 return false; |
3715 } | 3604 } |
3716 // report problem | 3605 // report problem |
3717 _errorReporter.reportErrorForNode( | 3606 _errorReporter.reportErrorForNode( |
3718 CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, | 3607 CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, node, [node.uri]); |
3719 node, | |
3720 [node.uri]); | |
3721 return true; | 3608 return true; |
3722 } | 3609 } |
3723 | 3610 |
3724 /** | 3611 /** |
3725 * For each class declaration, this method is called which verifies that all i
nherited members are | 3612 * For each class declaration, this method is called which verifies that all i
nherited members are |
3726 * inherited consistently. | 3613 * inherited consistently. |
3727 * | 3614 * |
3728 * @return `true` if and only if an error code is generated on the passed node | 3615 * @return `true` if and only if an error code is generated on the passed node |
3729 * See [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]. | 3616 * See [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]. |
3730 */ | 3617 */ |
(...skipping 17 matching lines...) Expand all Loading... |
3748 * This checks the given "typeReference" is not a type reference and that then
the "name" is | 3635 * This checks the given "typeReference" is not a type reference and that then
the "name" is |
3749 * reference to an instance member. | 3636 * reference to an instance member. |
3750 * | 3637 * |
3751 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, | 3638 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, |
3752 * or `null`, aka, the class element of 'C' in 'C.x', see | 3639 * or `null`, aka, the class element of 'C' in 'C.x', see |
3753 * [getTypeReference] | 3640 * [getTypeReference] |
3754 * @param name the accessed name to evaluate | 3641 * @param name the accessed name to evaluate |
3755 * @return `true` if and only if an error code is generated on the passed node | 3642 * @return `true` if and only if an error code is generated on the passed node |
3756 * See [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]. | 3643 * See [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]. |
3757 */ | 3644 */ |
3758 bool _checkForInstanceAccessToStaticMember(ClassElement typeReference, | 3645 bool _checkForInstanceAccessToStaticMember( |
3759 SimpleIdentifier name) { | 3646 ClassElement typeReference, SimpleIdentifier name) { |
3760 // OK, in comment | 3647 // OK, in comment |
3761 if (_isInComment) { | 3648 if (_isInComment) { |
3762 return false; | 3649 return false; |
3763 } | 3650 } |
3764 // OK, target is a type | 3651 // OK, target is a type |
3765 if (typeReference != null) { | 3652 if (typeReference != null) { |
3766 return false; | 3653 return false; |
3767 } | 3654 } |
3768 // prepare member Element | 3655 // prepare member Element |
3769 Element element = name.staticElement; | 3656 Element element = name.staticElement; |
3770 if (element is! ExecutableElement) { | 3657 if (element is! ExecutableElement) { |
3771 return false; | 3658 return false; |
3772 } | 3659 } |
3773 ExecutableElement executableElement = element as ExecutableElement; | 3660 ExecutableElement executableElement = element as ExecutableElement; |
3774 // OK, top-level element | 3661 // OK, top-level element |
3775 if (executableElement.enclosingElement is! ClassElement) { | 3662 if (executableElement.enclosingElement is! ClassElement) { |
3776 return false; | 3663 return false; |
3777 } | 3664 } |
3778 // OK, instance member | 3665 // OK, instance member |
3779 if (!executableElement.isStatic) { | 3666 if (!executableElement.isStatic) { |
3780 return false; | 3667 return false; |
3781 } | 3668 } |
3782 // report problem | 3669 // report problem |
3783 _errorReporter.reportErrorForNode( | 3670 _errorReporter.reportErrorForNode( |
3784 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, | 3671 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name, [ |
3785 name, | 3672 name.name |
3786 [name.name]); | 3673 ]); |
3787 return true; | 3674 return true; |
3788 } | 3675 } |
3789 | 3676 |
3790 /** | 3677 /** |
3791 * This checks whether the given [executableElement] collides with the name of
a static | 3678 * This checks whether the given [executableElement] collides with the name of
a static |
3792 * method in one of its superclasses, and reports the appropriate warning if i
t does. | 3679 * method in one of its superclasses, and reports the appropriate warning if i
t does. |
3793 * | 3680 * |
3794 * @param executableElement the method to check. | 3681 * @param executableElement the method to check. |
3795 * @param errorNameTarget the node to report problems on. | 3682 * @param errorNameTarget the node to report problems on. |
3796 * @return `true` if and only if a warning was generated. | 3683 * @return `true` if and only if a warning was generated. |
3797 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST
ATIC]. | 3684 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST
ATIC]. |
3798 */ | 3685 */ |
3799 bool | 3686 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic( |
3800 _checkForInstanceMethodNameCollidesWithSuperclassStatic(ExecutableElement
executableElement, | 3687 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) { |
3801 SimpleIdentifier errorNameTarget) { | |
3802 String executableElementName = executableElement.name; | 3688 String executableElementName = executableElement.name; |
3803 if (executableElement is! PropertyAccessorElement && | 3689 if (executableElement is! PropertyAccessorElement && |
3804 !executableElement.isOperator) { | 3690 !executableElement.isOperator) { |
3805 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>(); | 3691 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>(); |
3806 InterfaceType superclassType = _enclosingClass.supertype; | 3692 InterfaceType superclassType = _enclosingClass.supertype; |
3807 ClassElement superclassElement = | 3693 ClassElement superclassElement = |
3808 superclassType == null ? null : superclassType.element; | 3694 superclassType == null ? null : superclassType.element; |
3809 bool executableElementPrivate = | 3695 bool executableElementPrivate = |
3810 Identifier.isPrivateName(executableElementName); | 3696 Identifier.isPrivateName(executableElementName); |
3811 while (superclassElement != null && | 3697 while (superclassElement != null && |
3812 !visitedClasses.contains(superclassElement)) { | 3698 !visitedClasses.contains(superclassElement)) { |
3813 visitedClasses.add(superclassElement); | 3699 visitedClasses.add(superclassElement); |
3814 LibraryElement superclassLibrary = superclassElement.library; | 3700 LibraryElement superclassLibrary = superclassElement.library; |
3815 // Check fields. | 3701 // Check fields. |
3816 FieldElement fieldElt = superclassElement.getField(executableElementName
); | 3702 FieldElement fieldElt = |
| 3703 superclassElement.getField(executableElementName); |
3817 if (fieldElt != null) { | 3704 if (fieldElt != null) { |
3818 // Ignore if private in a different library - cannot collide. | 3705 // Ignore if private in a different library - cannot collide. |
3819 if (executableElementPrivate && | 3706 if (executableElementPrivate && |
3820 _currentLibrary != superclassLibrary) { | 3707 _currentLibrary != superclassLibrary) { |
3821 continue; | 3708 continue; |
3822 } | 3709 } |
3823 // instance vs. static | 3710 // instance vs. static |
3824 if (fieldElt.isStatic) { | 3711 if (fieldElt.isStatic) { |
3825 _errorReporter.reportErrorForNode( | 3712 _errorReporter.reportErrorForNode( |
3826 StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_
STATIC, | 3713 StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_
STATIC, |
3827 errorNameTarget, | 3714 errorNameTarget, [ |
3828 [executableElementName, fieldElt.enclosingElement.displayName]); | 3715 executableElementName, |
| 3716 fieldElt.enclosingElement.displayName |
| 3717 ]); |
3829 return true; | 3718 return true; |
3830 } | 3719 } |
3831 } | 3720 } |
3832 // Check methods. | 3721 // Check methods. |
3833 List<MethodElement> methodElements = superclassElement.methods; | 3722 List<MethodElement> methodElements = superclassElement.methods; |
3834 for (MethodElement methodElement in methodElements) { | 3723 for (MethodElement methodElement in methodElements) { |
3835 // We need the same name. | 3724 // We need the same name. |
3836 if (methodElement.name != executableElementName) { | 3725 if (methodElement.name != executableElementName) { |
3837 continue; | 3726 continue; |
3838 } | 3727 } |
3839 // Ignore if private in a different library - cannot collide. | 3728 // Ignore if private in a different library - cannot collide. |
3840 if (executableElementPrivate && | 3729 if (executableElementPrivate && |
3841 _currentLibrary != superclassLibrary) { | 3730 _currentLibrary != superclassLibrary) { |
3842 continue; | 3731 continue; |
3843 } | 3732 } |
3844 // instance vs. static | 3733 // instance vs. static |
3845 if (methodElement.isStatic) { | 3734 if (methodElement.isStatic) { |
3846 _errorReporter.reportErrorForNode( | 3735 _errorReporter.reportErrorForNode( |
3847 StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_
STATIC, | 3736 StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_
STATIC, |
3848 errorNameTarget, | 3737 errorNameTarget, [ |
3849 [executableElementName, methodElement.enclosingElement.displayNa
me]); | 3738 executableElementName, |
| 3739 methodElement.enclosingElement.displayName |
| 3740 ]); |
3850 return true; | 3741 return true; |
3851 } | 3742 } |
3852 } | 3743 } |
3853 superclassType = superclassElement.supertype; | 3744 superclassType = superclassElement.supertype; |
3854 superclassElement = | 3745 superclassElement = |
3855 superclassType == null ? null : superclassType.element; | 3746 superclassType == null ? null : superclassType.element; |
3856 } | 3747 } |
3857 } | 3748 } |
3858 return false; | 3749 return false; |
3859 } | 3750 } |
3860 | 3751 |
3861 /** | 3752 /** |
3862 * This verifies that an 'int' can be assigned to the parameter corresponding
to the given | 3753 * This verifies that an 'int' can be assigned to the parameter corresponding
to the given |
3863 * expression. This is used for prefix and postfix expressions where the argum
ent value is | 3754 * expression. This is used for prefix and postfix expressions where the argum
ent value is |
3864 * implicit. | 3755 * implicit. |
3865 * | 3756 * |
3866 * @param argument the expression to which the operator is being applied | 3757 * @param argument the expression to which the operator is being applied |
3867 * @return `true` if and only if an error code is generated on the passed node | 3758 * @return `true` if and only if an error code is generated on the passed node |
3868 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. | 3759 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. |
3869 */ | 3760 */ |
3870 bool _checkForIntNotAssignable(Expression argument) { | 3761 bool _checkForIntNotAssignable(Expression argument) { |
3871 if (argument == null) { | 3762 if (argument == null) { |
3872 return false; | 3763 return false; |
3873 } | 3764 } |
3874 ParameterElement staticParameterElement = argument.staticParameterElement; | 3765 ParameterElement staticParameterElement = argument.staticParameterElement; |
3875 DartType staticParameterType = | 3766 DartType staticParameterType = |
3876 staticParameterElement == null ? null : staticParameterElement.type; | 3767 staticParameterElement == null ? null : staticParameterElement.type; |
3877 return _checkForArgumentTypeNotAssignable( | 3768 return _checkForArgumentTypeNotAssignable(argument, staticParameterType, |
3878 argument, | 3769 _intType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); |
3879 staticParameterType, | |
3880 _intType, | |
3881 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); | |
3882 } | 3770 } |
3883 | 3771 |
3884 /** | 3772 /** |
3885 * This verifies that the passed [Annotation] isn't defined in a deferred libr
ary. | 3773 * This verifies that the passed [Annotation] isn't defined in a deferred libr
ary. |
3886 * | 3774 * |
3887 * @param node the [Annotation] | 3775 * @param node the [Annotation] |
3888 * @return `true` if and only if an error code is generated on the passed node | 3776 * @return `true` if and only if an error code is generated on the passed node |
3889 * See [CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY]. | 3777 * See [CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY]. |
3890 */ | 3778 */ |
3891 bool _checkForInvalidAnnotationFromDeferredLibrary(Annotation node) { | 3779 bool _checkForInvalidAnnotationFromDeferredLibrary(Annotation node) { |
(...skipping 15 matching lines...) Expand all Loading... |
3907 * @param lhs the left hand side expression | 3795 * @param lhs the left hand side expression |
3908 * @param rhs the right hand side expression | 3796 * @param rhs the right hand side expression |
3909 * @return `true` if and only if an error code is generated on the passed node | 3797 * @return `true` if and only if an error code is generated on the passed node |
3910 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT]. | 3798 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT]. |
3911 */ | 3799 */ |
3912 bool _checkForInvalidAssignment(Expression lhs, Expression rhs) { | 3800 bool _checkForInvalidAssignment(Expression lhs, Expression rhs) { |
3913 if (lhs == null || rhs == null) { | 3801 if (lhs == null || rhs == null) { |
3914 return false; | 3802 return false; |
3915 } | 3803 } |
3916 VariableElement leftVariableElement = getVariableElement(lhs); | 3804 VariableElement leftVariableElement = getVariableElement(lhs); |
3917 DartType leftType = | 3805 DartType leftType = (leftVariableElement == null) |
3918 (leftVariableElement == null) ? getStaticType(lhs) : leftVariableElement
.type; | 3806 ? getStaticType(lhs) |
| 3807 : leftVariableElement.type; |
3919 DartType staticRightType = getStaticType(rhs); | 3808 DartType staticRightType = getStaticType(rhs); |
3920 if (!staticRightType.isAssignableTo(leftType)) { | 3809 if (!staticRightType.isAssignableTo(leftType)) { |
3921 _errorReporter.reportTypeErrorForNode( | 3810 _errorReporter.reportTypeErrorForNode( |
3922 StaticTypeWarningCode.INVALID_ASSIGNMENT, | 3811 StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [ |
3923 rhs, | 3812 staticRightType, |
3924 [staticRightType, leftType]); | 3813 leftType |
| 3814 ]); |
3925 return true; | 3815 return true; |
3926 } | 3816 } |
3927 return false; | 3817 return false; |
3928 } | 3818 } |
3929 | 3819 |
3930 /** | 3820 /** |
3931 * Given an assignment using a compound assignment operator, this verifies tha
t the given | 3821 * Given an assignment using a compound assignment operator, this verifies tha
t the given |
3932 * assignment is valid. | 3822 * assignment is valid. |
3933 * | 3823 * |
3934 * @param node the assignment expression being tested | 3824 * @param node the assignment expression being tested |
3935 * @param lhs the left hand side expression | 3825 * @param lhs the left hand side expression |
3936 * @param rhs the right hand side expression | 3826 * @param rhs the right hand side expression |
3937 * @return `true` if and only if an error code is generated on the passed node | 3827 * @return `true` if and only if an error code is generated on the passed node |
3938 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT]. | 3828 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT]. |
3939 */ | 3829 */ |
3940 bool _checkForInvalidCompoundAssignment(AssignmentExpression node, | 3830 bool _checkForInvalidCompoundAssignment( |
3941 Expression lhs, Expression rhs) { | 3831 AssignmentExpression node, Expression lhs, Expression rhs) { |
3942 if (lhs == null) { | 3832 if (lhs == null) { |
3943 return false; | 3833 return false; |
3944 } | 3834 } |
3945 VariableElement leftVariableElement = getVariableElement(lhs); | 3835 VariableElement leftVariableElement = getVariableElement(lhs); |
3946 DartType leftType = | 3836 DartType leftType = (leftVariableElement == null) |
3947 (leftVariableElement == null) ? getStaticType(lhs) : leftVariableElement
.type; | 3837 ? getStaticType(lhs) |
| 3838 : leftVariableElement.type; |
3948 MethodElement invokedMethod = node.staticElement; | 3839 MethodElement invokedMethod = node.staticElement; |
3949 if (invokedMethod == null) { | 3840 if (invokedMethod == null) { |
3950 return false; | 3841 return false; |
3951 } | 3842 } |
3952 DartType rightType = invokedMethod.type.returnType; | 3843 DartType rightType = invokedMethod.type.returnType; |
3953 if (leftType == null || rightType == null) { | 3844 if (leftType == null || rightType == null) { |
3954 return false; | 3845 return false; |
3955 } | 3846 } |
3956 if (!rightType.isAssignableTo(leftType)) { | 3847 if (!rightType.isAssignableTo(leftType)) { |
3957 _errorReporter.reportTypeErrorForNode( | 3848 _errorReporter.reportTypeErrorForNode( |
3958 StaticTypeWarningCode.INVALID_ASSIGNMENT, | 3849 StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightType, leftType]); |
3959 rhs, | |
3960 [rightType, leftType]); | |
3961 return true; | 3850 return true; |
3962 } | 3851 } |
3963 return false; | 3852 return false; |
3964 } | 3853 } |
3965 | 3854 |
3966 /** | 3855 /** |
3967 * Check the given initializer to ensure that the field being initialized is a
valid field. | 3856 * Check the given initializer to ensure that the field being initialized is a
valid field. |
3968 * | 3857 * |
3969 * @param node the field initializer being checked | 3858 * @param node the field initializer being checked |
3970 * @param fieldName the field name from the [ConstructorFieldInitializer] | 3859 * @param fieldName the field name from the [ConstructorFieldInitializer] |
3971 * @param staticElement the static element from the name in the | 3860 * @param staticElement the static element from the name in the |
3972 * [ConstructorFieldInitializer] | 3861 * [ConstructorFieldInitializer] |
3973 */ | 3862 */ |
3974 void _checkForInvalidField(ConstructorFieldInitializer node, | 3863 void _checkForInvalidField(ConstructorFieldInitializer node, |
3975 SimpleIdentifier fieldName, Element staticElement) { | 3864 SimpleIdentifier fieldName, Element staticElement) { |
3976 if (staticElement is FieldElement) { | 3865 if (staticElement is FieldElement) { |
3977 FieldElement fieldElement = staticElement; | 3866 FieldElement fieldElement = staticElement; |
3978 if (fieldElement.isSynthetic) { | 3867 if (fieldElement.isSynthetic) { |
3979 _errorReporter.reportErrorForNode( | 3868 _errorReporter.reportErrorForNode( |
3980 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, | 3869 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, [ |
3981 node, | 3870 fieldName |
3982 [fieldName]); | 3871 ]); |
3983 } else if (fieldElement.isStatic) { | 3872 } else if (fieldElement.isStatic) { |
3984 _errorReporter.reportErrorForNode( | 3873 _errorReporter.reportErrorForNode( |
3985 CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, | 3874 CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [ |
3986 node, | 3875 fieldName |
3987 [fieldName]); | 3876 ]); |
3988 } | 3877 } |
3989 } else { | 3878 } else { |
3990 _errorReporter.reportErrorForNode( | 3879 _errorReporter.reportErrorForNode( |
3991 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, | 3880 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, [ |
3992 node, | 3881 fieldName |
3993 [fieldName]); | 3882 ]); |
3994 return; | 3883 return; |
3995 } | 3884 } |
3996 } | 3885 } |
3997 | 3886 |
3998 /** | 3887 /** |
3999 * Check to see whether the given function body has a modifier associated with
it, and report it | 3888 * Check to see whether the given function body has a modifier associated with
it, and report it |
4000 * as an error if it does. | 3889 * as an error if it does. |
4001 * | 3890 * |
4002 * @param body the function body being checked | 3891 * @param body the function body being checked |
4003 * @param errorCode the error code to be reported if a modifier is found | 3892 * @param errorCode the error code to be reported if a modifier is found |
4004 * @return `true` if an error was reported | 3893 * @return `true` if an error was reported |
4005 */ | 3894 */ |
4006 bool _checkForInvalidModifierOnBody(FunctionBody body, | 3895 bool _checkForInvalidModifierOnBody( |
4007 CompileTimeErrorCode errorCode) { | 3896 FunctionBody body, CompileTimeErrorCode errorCode) { |
4008 sc.Token keyword = body.keyword; | 3897 sc.Token keyword = body.keyword; |
4009 if (keyword != null) { | 3898 if (keyword != null) { |
4010 _errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]); | 3899 _errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]); |
4011 return true; | 3900 return true; |
4012 } | 3901 } |
4013 return false; | 3902 return false; |
4014 } | 3903 } |
4015 | 3904 |
4016 /** | 3905 /** |
4017 * This verifies that the usage of the passed 'this' is valid. | 3906 * This verifies that the usage of the passed 'this' is valid. |
4018 * | 3907 * |
4019 * @param node the 'this' expression to evaluate | 3908 * @param node the 'this' expression to evaluate |
4020 * @return `true` if and only if an error code is generated on the passed node | 3909 * @return `true` if and only if an error code is generated on the passed node |
4021 * See [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]. | 3910 * See [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]. |
4022 */ | 3911 */ |
4023 bool _checkForInvalidReferenceToThis(ThisExpression node) { | 3912 bool _checkForInvalidReferenceToThis(ThisExpression node) { |
4024 if (!_isThisInValidContext(node)) { | 3913 if (!_isThisInValidContext(node)) { |
4025 _errorReporter.reportErrorForNode( | 3914 _errorReporter.reportErrorForNode( |
4026 CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, | 3915 CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, node); |
4027 node); | |
4028 return true; | 3916 return true; |
4029 } | 3917 } |
4030 return false; | 3918 return false; |
4031 } | 3919 } |
4032 | 3920 |
4033 /** | 3921 /** |
4034 * Checks to ensure that the passed [ListLiteral] or [MapLiteral] does not hav
e a type | 3922 * Checks to ensure that the passed [ListLiteral] or [MapLiteral] does not hav
e a type |
4035 * parameter as a type argument. | 3923 * parameter as a type argument. |
4036 * | 3924 * |
4037 * @param arguments a non-`null`, non-empty [TypeName] node list from the resp
ective | 3925 * @param arguments a non-`null`, non-empty [TypeName] node list from the resp
ective |
4038 * [ListLiteral] or [MapLiteral] | 3926 * [ListLiteral] or [MapLiteral] |
4039 * @param errorCode either [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONS
T_LIST] or | 3927 * @param errorCode either [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONS
T_LIST] or |
4040 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP] | 3928 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP] |
4041 * @return `true` if and only if an error code is generated on the passed node | 3929 * @return `true` if and only if an error code is generated on the passed node |
4042 */ | 3930 */ |
4043 bool | 3931 bool _checkForInvalidTypeArgumentInConstTypedLiteral( |
4044 _checkForInvalidTypeArgumentInConstTypedLiteral(NodeList<TypeName> argumen
ts, | 3932 NodeList<TypeName> arguments, ErrorCode errorCode) { |
4045 ErrorCode errorCode) { | |
4046 bool foundError = false; | 3933 bool foundError = false; |
4047 for (TypeName typeName in arguments) { | 3934 for (TypeName typeName in arguments) { |
4048 if (typeName.type is TypeParameterType) { | 3935 if (typeName.type is TypeParameterType) { |
4049 _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); | 3936 _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); |
4050 foundError = true; | 3937 foundError = true; |
4051 } | 3938 } |
4052 } | 3939 } |
4053 return foundError; | 3940 return foundError; |
4054 } | 3941 } |
4055 | 3942 |
4056 /** | 3943 /** |
4057 * This verifies that the elements given [ListLiteral] are subtypes of the spe
cified element | 3944 * This verifies that the elements given [ListLiteral] are subtypes of the spe
cified element |
4058 * type. | 3945 * type. |
4059 * | 3946 * |
4060 * @param node the list literal to evaluate | 3947 * @param node the list literal to evaluate |
4061 * @param typeArguments the type arguments, always non-`null` | 3948 * @param typeArguments the type arguments, always non-`null` |
4062 * @return `true` if and only if an error code is generated on the passed node | 3949 * @return `true` if and only if an error code is generated on the passed node |
4063 * See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and | 3950 * See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and |
4064 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]. | 3951 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]. |
4065 */ | 3952 */ |
4066 bool _checkForListElementTypeNotAssignable(ListLiteral node, | 3953 bool _checkForListElementTypeNotAssignable( |
4067 TypeArgumentList typeArguments) { | 3954 ListLiteral node, TypeArgumentList typeArguments) { |
4068 NodeList<TypeName> typeNames = typeArguments.arguments; | 3955 NodeList<TypeName> typeNames = typeArguments.arguments; |
4069 if (typeNames.length < 1) { | 3956 if (typeNames.length < 1) { |
4070 return false; | 3957 return false; |
4071 } | 3958 } |
4072 DartType listElementType = typeNames[0].type; | 3959 DartType listElementType = typeNames[0].type; |
4073 // Check every list element. | 3960 // Check every list element. |
4074 bool hasProblems = false; | 3961 bool hasProblems = false; |
4075 for (Expression element in node.elements) { | 3962 for (Expression element in node.elements) { |
4076 if (node.constKeyword != null) { | 3963 if (node.constKeyword != null) { |
4077 // TODO(paulberry): this error should be based on the actual type of the | 3964 // TODO(paulberry): this error should be based on the actual type of the |
4078 // list element, not the static type. See dartbug.com/21119. | 3965 // list element, not the static type. See dartbug.com/21119. |
4079 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | 3966 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(element, |
4080 element, | |
4081 listElementType, | 3967 listElementType, |
4082 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { | 3968 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { |
4083 hasProblems = true; | 3969 hasProblems = true; |
4084 } | 3970 } |
4085 } | 3971 } |
4086 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | 3972 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(element, |
4087 element, | |
4088 listElementType, | 3973 listElementType, |
4089 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { | 3974 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { |
4090 hasProblems = true; | 3975 hasProblems = true; |
4091 } | 3976 } |
4092 } | 3977 } |
4093 return hasProblems; | 3978 return hasProblems; |
4094 } | 3979 } |
4095 | 3980 |
4096 /** | 3981 /** |
4097 * This verifies that the key/value of entries of the given [MapLiteral] are s
ubtypes of the | 3982 * This verifies that the key/value of entries of the given [MapLiteral] are s
ubtypes of the |
4098 * key/value types specified in the type arguments. | 3983 * key/value types specified in the type arguments. |
4099 * | 3984 * |
4100 * @param node the map literal to evaluate | 3985 * @param node the map literal to evaluate |
4101 * @param typeArguments the type arguments, always non-`null` | 3986 * @param typeArguments the type arguments, always non-`null` |
4102 * @return `true` if and only if an error code is generated on the passed node | 3987 * @return `true` if and only if an error code is generated on the passed node |
4103 * See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], | 3988 * See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], |
4104 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], | 3989 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], |
4105 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and | 3990 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and |
4106 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. | 3991 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. |
4107 */ | 3992 */ |
4108 bool _checkForMapTypeNotAssignable(MapLiteral node, | 3993 bool _checkForMapTypeNotAssignable( |
4109 TypeArgumentList typeArguments) { | 3994 MapLiteral node, TypeArgumentList typeArguments) { |
4110 // Prepare maps key/value types. | 3995 // Prepare maps key/value types. |
4111 NodeList<TypeName> typeNames = typeArguments.arguments; | 3996 NodeList<TypeName> typeNames = typeArguments.arguments; |
4112 if (typeNames.length < 2) { | 3997 if (typeNames.length < 2) { |
4113 return false; | 3998 return false; |
4114 } | 3999 } |
4115 DartType keyType = typeNames[0].type; | 4000 DartType keyType = typeNames[0].type; |
4116 DartType valueType = typeNames[1].type; | 4001 DartType valueType = typeNames[1].type; |
4117 // Check every map entry. | 4002 // Check every map entry. |
4118 bool hasProblems = false; | 4003 bool hasProblems = false; |
4119 NodeList<MapLiteralEntry> entries = node.entries; | 4004 NodeList<MapLiteralEntry> entries = node.entries; |
4120 for (MapLiteralEntry entry in entries) { | 4005 for (MapLiteralEntry entry in entries) { |
4121 Expression key = entry.key; | 4006 Expression key = entry.key; |
4122 Expression value = entry.value; | 4007 Expression value = entry.value; |
4123 if (node.constKeyword != null) { | 4008 if (node.constKeyword != null) { |
4124 // TODO(paulberry): this error should be based on the actual type of the | 4009 // TODO(paulberry): this error should be based on the actual type of the |
4125 // list element, not the static type. See dartbug.com/21119. | 4010 // list element, not the static type. See dartbug.com/21119. |
4126 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | 4011 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(key, keyType, |
4127 key, | |
4128 keyType, | |
4129 CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) { | 4012 CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) { |
4130 hasProblems = true; | 4013 hasProblems = true; |
4131 } | 4014 } |
4132 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | 4015 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(value, |
4133 value, | |
4134 valueType, | 4016 valueType, |
4135 CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) { | 4017 CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) { |
4136 hasProblems = true; | 4018 hasProblems = true; |
4137 } | 4019 } |
4138 } | 4020 } |
4139 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | 4021 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( |
4140 key, | 4022 key, keyType, StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) { |
4141 keyType, | |
4142 StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) { | |
4143 hasProblems = true; | 4023 hasProblems = true; |
4144 } | 4024 } |
4145 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | 4025 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( |
4146 value, | 4026 value, valueType, StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) { |
4147 valueType, | |
4148 StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) { | |
4149 hasProblems = true; | 4027 hasProblems = true; |
4150 } | 4028 } |
4151 } | 4029 } |
4152 return hasProblems; | 4030 return hasProblems; |
4153 } | 4031 } |
4154 | 4032 |
4155 /** | 4033 /** |
4156 * This verifies that the [enclosingClass] does not define members with the sa
me name as | 4034 * This verifies that the [enclosingClass] does not define members with the sa
me name as |
4157 * the enclosing class. | 4035 * the enclosing class. |
4158 * | 4036 * |
4159 * @return `true` if and only if an error code is generated on the passed node | 4037 * @return `true` if and only if an error code is generated on the passed node |
4160 * See [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]. | 4038 * See [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]. |
4161 */ | 4039 */ |
4162 bool _checkForMemberWithClassName() { | 4040 bool _checkForMemberWithClassName() { |
4163 if (_enclosingClass == null) { | 4041 if (_enclosingClass == null) { |
4164 return false; | 4042 return false; |
4165 } | 4043 } |
4166 String className = _enclosingClass.name; | 4044 String className = _enclosingClass.name; |
4167 if (className == null) { | 4045 if (className == null) { |
4168 return false; | 4046 return false; |
4169 } | 4047 } |
4170 bool problemReported = false; | 4048 bool problemReported = false; |
4171 // check accessors | 4049 // check accessors |
4172 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { | 4050 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { |
4173 if (className == accessor.name) { | 4051 if (className == accessor.name) { |
4174 _errorReporter.reportErrorForOffset( | 4052 _errorReporter.reportErrorForOffset( |
4175 CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME, | 4053 CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME, accessor.nameOffset, |
4176 accessor.nameOffset, | |
4177 className.length); | 4054 className.length); |
4178 problemReported = true; | 4055 problemReported = true; |
4179 } | 4056 } |
4180 } | 4057 } |
4181 // don't check methods, they would be constructors | 4058 // don't check methods, they would be constructors |
4182 // done | 4059 // done |
4183 return problemReported; | 4060 return problemReported; |
4184 } | 4061 } |
4185 | 4062 |
4186 /** | 4063 /** |
4187 * Check to make sure that all similarly typed accessors are of the same type
(including inherited | 4064 * Check to make sure that all similarly typed accessors are of the same type
(including inherited |
4188 * accessors). | 4065 * accessors). |
4189 * | 4066 * |
4190 * @param node the accessor currently being visited | 4067 * @param node the accessor currently being visited |
4191 * @return `true` if and only if an error code is generated on the passed node | 4068 * @return `true` if and only if an error code is generated on the passed node |
4192 * See [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES], and | 4069 * See [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES], and |
4193 * [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE]. | 4070 * [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE]. |
4194 */ | 4071 */ |
4195 bool _checkForMismatchedAccessorTypes(Declaration accessorDeclaration, | 4072 bool _checkForMismatchedAccessorTypes( |
4196 String accessorTextName) { | 4073 Declaration accessorDeclaration, String accessorTextName) { |
4197 ExecutableElement accessorElement = | 4074 ExecutableElement accessorElement = |
4198 accessorDeclaration.element as ExecutableElement; | 4075 accessorDeclaration.element as ExecutableElement; |
4199 if (accessorElement is! PropertyAccessorElement) { | 4076 if (accessorElement is! PropertyAccessorElement) { |
4200 return false; | 4077 return false; |
4201 } | 4078 } |
4202 PropertyAccessorElement propertyAccessorElement = | 4079 PropertyAccessorElement propertyAccessorElement = |
4203 accessorElement as PropertyAccessorElement; | 4080 accessorElement as PropertyAccessorElement; |
4204 PropertyAccessorElement counterpartAccessor = null; | 4081 PropertyAccessorElement counterpartAccessor = null; |
4205 ClassElement enclosingClassForCounterpart = null; | 4082 ClassElement enclosingClassForCounterpart = null; |
4206 if (propertyAccessorElement.isGetter) { | 4083 if (propertyAccessorElement.isGetter) { |
4207 counterpartAccessor = propertyAccessorElement.correspondingSetter; | 4084 counterpartAccessor = propertyAccessorElement.correspondingSetter; |
4208 } else { | 4085 } else { |
4209 counterpartAccessor = propertyAccessorElement.correspondingGetter; | 4086 counterpartAccessor = propertyAccessorElement.correspondingGetter; |
4210 // If the setter and getter are in the same enclosing element, return, | 4087 // If the setter and getter are in the same enclosing element, return, |
4211 // this prevents having MISMATCHED_GETTER_AND_SETTER_TYPES reported twice. | 4088 // this prevents having MISMATCHED_GETTER_AND_SETTER_TYPES reported twice. |
4212 if (counterpartAccessor != null && | 4089 if (counterpartAccessor != null && |
4213 identical( | 4090 identical(counterpartAccessor.enclosingElement, |
4214 counterpartAccessor.enclosingElement, | |
4215 propertyAccessorElement.enclosingElement)) { | 4091 propertyAccessorElement.enclosingElement)) { |
4216 return false; | 4092 return false; |
4217 } | 4093 } |
4218 } | 4094 } |
4219 if (counterpartAccessor == null) { | 4095 if (counterpartAccessor == null) { |
4220 // If the accessor is declared in a class, check the superclasses. | 4096 // If the accessor is declared in a class, check the superclasses. |
4221 if (_enclosingClass != null) { | 4097 if (_enclosingClass != null) { |
4222 // Figure out the correct identifier to lookup in the inheritance graph, | 4098 // Figure out the correct identifier to lookup in the inheritance graph, |
4223 // if 'x', then 'x=', or if 'x=', then 'x'. | 4099 // if 'x', then 'x=', or if 'x=', then 'x'. |
4224 String lookupIdentifier = propertyAccessorElement.name; | 4100 String lookupIdentifier = propertyAccessorElement.name; |
4225 if (StringUtilities.endsWithChar(lookupIdentifier, 0x3D)) { | 4101 if (StringUtilities.endsWithChar(lookupIdentifier, 0x3D)) { |
4226 lookupIdentifier = | 4102 lookupIdentifier = |
4227 lookupIdentifier.substring(0, lookupIdentifier.length - 1); | 4103 lookupIdentifier.substring(0, lookupIdentifier.length - 1); |
4228 } else { | 4104 } else { |
4229 lookupIdentifier += "="; | 4105 lookupIdentifier += "="; |
4230 } | 4106 } |
4231 // lookup with the identifier. | 4107 // lookup with the identifier. |
4232 ExecutableElement elementFromInheritance = | 4108 ExecutableElement elementFromInheritance = _inheritanceManager |
4233 _inheritanceManager.lookupInheritance(_enclosingClass, lookupIdentif
ier); | 4109 .lookupInheritance(_enclosingClass, lookupIdentifier); |
4234 // Verify that we found something, and that it is an accessor | 4110 // Verify that we found something, and that it is an accessor |
4235 if (elementFromInheritance != null && | 4111 if (elementFromInheritance != null && |
4236 elementFromInheritance is PropertyAccessorElement) { | 4112 elementFromInheritance is PropertyAccessorElement) { |
4237 enclosingClassForCounterpart = | 4113 enclosingClassForCounterpart = |
4238 elementFromInheritance.enclosingElement as ClassElement; | 4114 elementFromInheritance.enclosingElement as ClassElement; |
4239 counterpartAccessor = elementFromInheritance; | 4115 counterpartAccessor = elementFromInheritance; |
4240 } | 4116 } |
4241 } | 4117 } |
4242 if (counterpartAccessor == null) { | 4118 if (counterpartAccessor == null) { |
4243 return false; | 4119 return false; |
(...skipping 11 matching lines...) Expand all Loading... |
4255 getterType = _getGetterType(counterpartAccessor); | 4131 getterType = _getGetterType(counterpartAccessor); |
4256 } | 4132 } |
4257 // If either types are not assignable to each other, report an error | 4133 // If either types are not assignable to each other, report an error |
4258 // (if the getter is null, it is dynamic which is assignable to everything). | 4134 // (if the getter is null, it is dynamic which is assignable to everything). |
4259 if (setterType != null && | 4135 if (setterType != null && |
4260 getterType != null && | 4136 getterType != null && |
4261 !getterType.isAssignableTo(setterType)) { | 4137 !getterType.isAssignableTo(setterType)) { |
4262 if (enclosingClassForCounterpart == null) { | 4138 if (enclosingClassForCounterpart == null) { |
4263 _errorReporter.reportTypeErrorForNode( | 4139 _errorReporter.reportTypeErrorForNode( |
4264 StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, | 4140 StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, |
4265 accessorDeclaration, | 4141 accessorDeclaration, [accessorTextName, setterType, getterType]); |
4266 [accessorTextName, setterType, getterType]); | |
4267 return true; | 4142 return true; |
4268 } else { | 4143 } else { |
4269 _errorReporter.reportTypeErrorForNode( | 4144 _errorReporter.reportTypeErrorForNode( |
4270 StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, | 4145 StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, |
4271 accessorDeclaration, | 4146 accessorDeclaration, [ |
4272 [ | 4147 accessorTextName, |
4273 accessorTextName, | 4148 setterType, |
4274 setterType, | 4149 getterType, |
4275 getterType, | 4150 enclosingClassForCounterpart.displayName |
4276 enclosingClassForCounterpart.displayName]); | 4151 ]); |
4277 } | 4152 } |
4278 } | 4153 } |
4279 return false; | 4154 return false; |
4280 } | 4155 } |
4281 | 4156 |
4282 /** | 4157 /** |
4283 * Check to make sure that switch statements whose static type is an enum type
either have a | 4158 * Check to make sure that switch statements whose static type is an enum type
either have a |
4284 * default case or include all of the enum constants. | 4159 * default case or include all of the enum constants. |
4285 * | 4160 * |
4286 * @param statement the switch statement to check | 4161 * @param statement the switch statement to check |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4322 if (constantName != null) { | 4197 if (constantName != null) { |
4323 constantNames.remove(constantName); | 4198 constantNames.remove(constantName); |
4324 } | 4199 } |
4325 } | 4200 } |
4326 int nameCount = constantNames.length; | 4201 int nameCount = constantNames.length; |
4327 if (nameCount == 0) { | 4202 if (nameCount == 0) { |
4328 return false; | 4203 return false; |
4329 } | 4204 } |
4330 for (int i = 0; i < nameCount; i++) { | 4205 for (int i = 0; i < nameCount; i++) { |
4331 _errorReporter.reportErrorForNode( | 4206 _errorReporter.reportErrorForNode( |
4332 CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, | 4207 CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, statement, [ |
4333 statement, | 4208 constantNames[i] |
4334 [constantNames[i]]); | 4209 ]); |
4335 } | 4210 } |
4336 return true; | 4211 return true; |
4337 } | 4212 } |
4338 | 4213 |
4339 /** | 4214 /** |
4340 * This verifies that the given function body does not contain return statemen
ts that both have | 4215 * This verifies that the given function body does not contain return statemen
ts that both have |
4341 * and do not have return values. | 4216 * and do not have return values. |
4342 * | 4217 * |
4343 * @param node the function body being tested | 4218 * @param node the function body being tested |
4344 * @return `true` if and only if an error code is generated on the passed node | 4219 * @return `true` if and only if an error code is generated on the passed node |
4345 * See [StaticWarningCode.MIXED_RETURN_TYPES]. | 4220 * See [StaticWarningCode.MIXED_RETURN_TYPES]. |
4346 */ | 4221 */ |
4347 bool _checkForMixedReturns(BlockFunctionBody node) { | 4222 bool _checkForMixedReturns(BlockFunctionBody node) { |
4348 if (_hasReturnWithoutValue) { | 4223 if (_hasReturnWithoutValue) { |
4349 return false; | 4224 return false; |
4350 } | 4225 } |
4351 int withCount = _returnsWith.length; | 4226 int withCount = _returnsWith.length; |
4352 int withoutCount = _returnsWithout.length; | 4227 int withoutCount = _returnsWithout.length; |
4353 if (withCount > 0 && withoutCount > 0) { | 4228 if (withCount > 0 && withoutCount > 0) { |
4354 for (int i = 0; i < withCount; i++) { | 4229 for (int i = 0; i < withCount; i++) { |
4355 _errorReporter.reportErrorForToken( | 4230 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, |
4356 StaticWarningCode.MIXED_RETURN_TYPES, | |
4357 _returnsWith[i].returnKeyword); | 4231 _returnsWith[i].returnKeyword); |
4358 } | 4232 } |
4359 for (int i = 0; i < withoutCount; i++) { | 4233 for (int i = 0; i < withoutCount; i++) { |
4360 _errorReporter.reportErrorForToken( | 4234 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, |
4361 StaticWarningCode.MIXED_RETURN_TYPES, | |
4362 _returnsWithout[i].returnKeyword); | 4235 _returnsWithout[i].returnKeyword); |
4363 } | 4236 } |
4364 return true; | 4237 return true; |
4365 } | 4238 } |
4366 return false; | 4239 return false; |
4367 } | 4240 } |
4368 | 4241 |
4369 /** | 4242 /** |
4370 * This verifies that the passed mixin does not have an explicitly declared co
nstructor. | 4243 * This verifies that the passed mixin does not have an explicitly declared co
nstructor. |
4371 * | 4244 * |
4372 * @param mixinName the node to report problem on | 4245 * @param mixinName the node to report problem on |
4373 * @param mixinElement the mixing to evaluate | 4246 * @param mixinElement the mixing to evaluate |
4374 * @return `true` if and only if an error code is generated on the passed node | 4247 * @return `true` if and only if an error code is generated on the passed node |
4375 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]. | 4248 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]. |
4376 */ | 4249 */ |
4377 bool _checkForMixinDeclaresConstructor(TypeName mixinName, | 4250 bool _checkForMixinDeclaresConstructor( |
4378 ClassElement mixinElement) { | 4251 TypeName mixinName, ClassElement mixinElement) { |
4379 for (ConstructorElement constructor in mixinElement.constructors) { | 4252 for (ConstructorElement constructor in mixinElement.constructors) { |
4380 if (!constructor.isSynthetic && !constructor.isFactory) { | 4253 if (!constructor.isSynthetic && !constructor.isFactory) { |
4381 _errorReporter.reportErrorForNode( | 4254 _errorReporter.reportErrorForNode( |
4382 CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, | 4255 CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, mixinName, [ |
4383 mixinName, | 4256 mixinElement.name |
4384 [mixinElement.name]); | 4257 ]); |
4385 return true; | 4258 return true; |
4386 } | 4259 } |
4387 } | 4260 } |
4388 return false; | 4261 return false; |
4389 } | 4262 } |
4390 | 4263 |
4391 /** | 4264 /** |
4392 * This verifies that the passed mixin has the 'Object' superclass. | 4265 * This verifies that the passed mixin has the 'Object' superclass. |
4393 * | 4266 * |
4394 * @param mixinName the node to report problem on | 4267 * @param mixinName the node to report problem on |
4395 * @param mixinElement the mixing to evaluate | 4268 * @param mixinElement the mixing to evaluate |
4396 * @return `true` if and only if an error code is generated on the passed node | 4269 * @return `true` if and only if an error code is generated on the passed node |
4397 * See [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]. | 4270 * See [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]. |
4398 */ | 4271 */ |
4399 bool _checkForMixinInheritsNotFromObject(TypeName mixinName, | 4272 bool _checkForMixinInheritsNotFromObject( |
4400 ClassElement mixinElement) { | 4273 TypeName mixinName, ClassElement mixinElement) { |
4401 InterfaceType mixinSupertype = mixinElement.supertype; | 4274 InterfaceType mixinSupertype = mixinElement.supertype; |
4402 if (mixinSupertype != null) { | 4275 if (mixinSupertype != null) { |
4403 if (!mixinSupertype.isObject || | 4276 if (!mixinSupertype.isObject || |
4404 !mixinElement.isTypedef && mixinElement.mixins.length != 0) { | 4277 !mixinElement.isTypedef && mixinElement.mixins.length != 0) { |
4405 _errorReporter.reportErrorForNode( | 4278 _errorReporter.reportErrorForNode( |
4406 CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, | 4279 CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, mixinName, [ |
4407 mixinName, | 4280 mixinElement.name |
4408 [mixinElement.name]); | 4281 ]); |
4409 return true; | 4282 return true; |
4410 } | 4283 } |
4411 } | 4284 } |
4412 return false; | 4285 return false; |
4413 } | 4286 } |
4414 | 4287 |
4415 /** | 4288 /** |
4416 * This verifies that the passed mixin does not reference 'super'. | 4289 * This verifies that the passed mixin does not reference 'super'. |
4417 * | 4290 * |
4418 * @param mixinName the node to report problem on | 4291 * @param mixinName the node to report problem on |
4419 * @param mixinElement the mixing to evaluate | 4292 * @param mixinElement the mixing to evaluate |
4420 * @return `true` if and only if an error code is generated on the passed node | 4293 * @return `true` if and only if an error code is generated on the passed node |
4421 * See [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]. | 4294 * See [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]. |
4422 */ | 4295 */ |
4423 bool _checkForMixinReferencesSuper(TypeName mixinName, | 4296 bool _checkForMixinReferencesSuper( |
4424 ClassElement mixinElement) { | 4297 TypeName mixinName, ClassElement mixinElement) { |
4425 if (mixinElement.hasReferenceToSuper) { | 4298 if (mixinElement.hasReferenceToSuper) { |
4426 _errorReporter.reportErrorForNode( | 4299 _errorReporter.reportErrorForNode( |
4427 CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, | 4300 CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, mixinName, [ |
4428 mixinName, | 4301 mixinElement.name |
4429 [mixinElement.name]); | 4302 ]); |
4430 } | 4303 } |
4431 return false; | 4304 return false; |
4432 } | 4305 } |
4433 | 4306 |
4434 /** | 4307 /** |
4435 * This verifies that the passed constructor has at most one 'super' initializ
er. | 4308 * This verifies that the passed constructor has at most one 'super' initializ
er. |
4436 * | 4309 * |
4437 * @param node the constructor declaration to evaluate | 4310 * @param node the constructor declaration to evaluate |
4438 * @return `true` if and only if an error code is generated on the passed node | 4311 * @return `true` if and only if an error code is generated on the passed node |
4439 * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]. | 4312 * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]. |
4440 */ | 4313 */ |
4441 bool _checkForMultipleSuperInitializers(ConstructorDeclaration node) { | 4314 bool _checkForMultipleSuperInitializers(ConstructorDeclaration node) { |
4442 int numSuperInitializers = 0; | 4315 int numSuperInitializers = 0; |
4443 for (ConstructorInitializer initializer in node.initializers) { | 4316 for (ConstructorInitializer initializer in node.initializers) { |
4444 if (initializer is SuperConstructorInvocation) { | 4317 if (initializer is SuperConstructorInvocation) { |
4445 numSuperInitializers++; | 4318 numSuperInitializers++; |
4446 if (numSuperInitializers > 1) { | 4319 if (numSuperInitializers > 1) { |
4447 _errorReporter.reportErrorForNode( | 4320 _errorReporter.reportErrorForNode( |
4448 CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, | 4321 CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer); |
4449 initializer); | |
4450 } | 4322 } |
4451 } | 4323 } |
4452 } | 4324 } |
4453 return numSuperInitializers > 0; | 4325 return numSuperInitializers > 0; |
4454 } | 4326 } |
4455 | 4327 |
4456 /** | 4328 /** |
4457 * Checks to ensure that native function bodies can only in SDK code. | 4329 * Checks to ensure that native function bodies can only in SDK code. |
4458 * | 4330 * |
4459 * @param node the native function body to test | 4331 * @param node the native function body to test |
4460 * @return `true` if and only if an error code is generated on the passed node | 4332 * @return `true` if and only if an error code is generated on the passed node |
4461 * See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]. | 4333 * See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]. |
4462 */ | 4334 */ |
4463 bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) { | 4335 bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) { |
4464 if (!_isInSystemLibrary && !_hasExtUri) { | 4336 if (!_isInSystemLibrary && !_hasExtUri) { |
4465 _errorReporter.reportErrorForNode( | 4337 _errorReporter.reportErrorForNode( |
4466 ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, | 4338 ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, node); |
4467 node); | |
4468 return true; | 4339 return true; |
4469 } | 4340 } |
4470 return false; | 4341 return false; |
4471 } | 4342 } |
4472 | 4343 |
4473 /** | 4344 /** |
4474 * This verifies that the passed 'new' instance creation expression invokes ex
isting constructor. | 4345 * This verifies that the passed 'new' instance creation expression invokes ex
isting constructor. |
4475 * | 4346 * |
4476 * This method assumes that the instance creation was tested to be 'new' befor
e being called. | 4347 * This method assumes that the instance creation was tested to be 'new' befor
e being called. |
4477 * | 4348 * |
(...skipping 16 matching lines...) Expand all Loading... |
4494 // We have already reported the error. | 4365 // We have already reported the error. |
4495 return false; | 4366 return false; |
4496 } | 4367 } |
4497 } | 4368 } |
4498 // prepare class name | 4369 // prepare class name |
4499 Identifier className = typeName.name; | 4370 Identifier className = typeName.name; |
4500 // report as named or default constructor absence | 4371 // report as named or default constructor absence |
4501 SimpleIdentifier name = constructorName.name; | 4372 SimpleIdentifier name = constructorName.name; |
4502 if (name != null) { | 4373 if (name != null) { |
4503 _errorReporter.reportErrorForNode( | 4374 _errorReporter.reportErrorForNode( |
4504 StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, | 4375 StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, name, [ |
4505 name, | 4376 className, |
4506 [className, name]); | 4377 name |
| 4378 ]); |
4507 } else { | 4379 } else { |
4508 _errorReporter.reportErrorForNode( | 4380 _errorReporter.reportErrorForNode( |
4509 StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, | 4381 StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, |
4510 constructorName, | 4382 constructorName, [className]); |
4511 [className]); | |
4512 } | 4383 } |
4513 return true; | 4384 return true; |
4514 } | 4385 } |
4515 | 4386 |
4516 /** | 4387 /** |
4517 * This checks that if the passed class declaration implicitly calls default c
onstructor of its | 4388 * This checks that if the passed class declaration implicitly calls default c
onstructor of its |
4518 * superclass, there should be such default constructor - implicit or explicit
. | 4389 * superclass, there should be such default constructor - implicit or explicit
. |
4519 * | 4390 * |
4520 * @param node the [ClassDeclaration] to evaluate | 4391 * @param node the [ClassDeclaration] to evaluate |
4521 * @return `true` if and only if an error code is generated on the passed node | 4392 * @return `true` if and only if an error code is generated on the passed node |
(...skipping 15 matching lines...) Expand all Loading... |
4537 if (superType == null) { | 4408 if (superType == null) { |
4538 return false; | 4409 return false; |
4539 } | 4410 } |
4540 ClassElement superElement = superType.element; | 4411 ClassElement superElement = superType.element; |
4541 // try to find default generative super constructor | 4412 // try to find default generative super constructor |
4542 ConstructorElement superUnnamedConstructor = | 4413 ConstructorElement superUnnamedConstructor = |
4543 superElement.unnamedConstructor; | 4414 superElement.unnamedConstructor; |
4544 if (superUnnamedConstructor != null) { | 4415 if (superUnnamedConstructor != null) { |
4545 if (superUnnamedConstructor.isFactory) { | 4416 if (superUnnamedConstructor.isFactory) { |
4546 _errorReporter.reportErrorForNode( | 4417 _errorReporter.reportErrorForNode( |
4547 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, | 4418 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.name, [ |
4548 node.name, | 4419 superUnnamedConstructor |
4549 [superUnnamedConstructor]); | 4420 ]); |
4550 return true; | 4421 return true; |
4551 } | 4422 } |
4552 if (superUnnamedConstructor.isDefaultConstructor && | 4423 if (superUnnamedConstructor.isDefaultConstructor && |
4553 _enclosingClass.isSuperConstructorAccessible(superUnnamedConstructor))
{ | 4424 _enclosingClass |
| 4425 .isSuperConstructorAccessible(superUnnamedConstructor)) { |
4554 return true; | 4426 return true; |
4555 } | 4427 } |
4556 } | 4428 } |
4557 // report problem | 4429 // report problem |
4558 _errorReporter.reportErrorForNode( | 4430 _errorReporter.reportErrorForNode( |
4559 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, | 4431 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, node.name, [ |
4560 node.name, | 4432 superType.displayName |
4561 [superType.displayName]); | 4433 ]); |
4562 return true; | 4434 return true; |
4563 } | 4435 } |
4564 | 4436 |
4565 /** | 4437 /** |
4566 * This checks that passed class declaration overrides all members required by
its superclasses | 4438 * This checks that passed class declaration overrides all members required by
its superclasses |
4567 * and interfaces. | 4439 * and interfaces. |
4568 * | 4440 * |
4569 * @param classNameNode the [SimpleIdentifier] to be used if there is a violat
ion, this is | 4441 * @param classNameNode the [SimpleIdentifier] to be used if there is a violat
ion, this is |
4570 * either the named from the [ClassDeclaration] or from the [ClassTyp
eAlias]. | 4442 * either the named from the [ClassDeclaration] or from the [ClassTyp
eAlias]. |
4571 * @return `true` if and only if an error code is generated on the passed node | 4443 * @return `true` if and only if an error code is generated on the passed node |
4572 * See [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], | 4444 * See [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], |
4573 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO], | 4445 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO], |
4574 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE], | 4446 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE], |
4575 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR], and | 4447 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR], and |
4576 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS]. | 4448 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS]. |
4577 */ | 4449 */ |
4578 bool | 4450 bool _checkForNonAbstractClassInheritsAbstractMember( |
4579 _checkForNonAbstractClassInheritsAbstractMember(SimpleIdentifier className
Node) { | 4451 SimpleIdentifier classNameNode) { |
4580 if (_enclosingClass.isAbstract) { | 4452 if (_enclosingClass.isAbstract) { |
4581 return false; | 4453 return false; |
4582 } | 4454 } |
4583 // | 4455 // |
4584 // Store in local sets the set of all method and accessor names | 4456 // Store in local sets the set of all method and accessor names |
4585 // | 4457 // |
4586 MethodElement method = | 4458 MethodElement method = |
4587 _enclosingClass.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME); | 4459 _enclosingClass.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME); |
4588 if (method != null) { | 4460 if (method != null) { |
4589 // If the enclosing class declares the method noSuchMethod(), then return. | 4461 // If the enclosing class declares the method noSuchMethod(), then return. |
4590 // From Spec: It is a static warning if a concrete class does not have an | 4462 // From Spec: It is a static warning if a concrete class does not have an |
4591 // implementation for a method in any of its superinterfaces unless it | 4463 // implementation for a method in any of its superinterfaces unless it |
4592 // declares its own noSuchMethod method (7.10). | 4464 // declares its own noSuchMethod method (7.10). |
4593 return false; | 4465 return false; |
4594 } | 4466 } |
4595 HashSet<ExecutableElement> missingOverrides = | 4467 HashSet<ExecutableElement> missingOverrides = |
4596 new HashSet<ExecutableElement>(); | 4468 new HashSet<ExecutableElement>(); |
4597 // | 4469 // |
4598 // Loop through the set of all executable elements declared in the implicit | 4470 // Loop through the set of all executable elements declared in the implicit |
4599 // interface. | 4471 // interface. |
4600 // | 4472 // |
4601 MemberMap membersInheritedFromInterfaces = | 4473 MemberMap membersInheritedFromInterfaces = _inheritanceManager |
4602 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingCla
ss); | 4474 .getMapOfMembersInheritedFromInterfaces(_enclosingClass); |
4603 MemberMap membersInheritedFromSuperclasses = | 4475 MemberMap membersInheritedFromSuperclasses = _inheritanceManager |
4604 _inheritanceManager.getMapOfMembersInheritedFromClasses(_enclosingClass)
; | 4476 .getMapOfMembersInheritedFromClasses(_enclosingClass); |
4605 for (int i = 0; i < membersInheritedFromInterfaces.size; i++) { | 4477 for (int i = 0; i < membersInheritedFromInterfaces.size; i++) { |
4606 String memberName = membersInheritedFromInterfaces.getKey(i); | 4478 String memberName = membersInheritedFromInterfaces.getKey(i); |
4607 ExecutableElement executableElt = | 4479 ExecutableElement executableElt = |
4608 membersInheritedFromInterfaces.getValue(i); | 4480 membersInheritedFromInterfaces.getValue(i); |
4609 if (memberName == null) { | 4481 if (memberName == null) { |
4610 break; | 4482 break; |
4611 } | 4483 } |
4612 // If the element is not synthetic and can be determined to be defined in | 4484 // If the element is not synthetic and can be determined to be defined in |
4613 // Object, skip it. | 4485 // Object, skip it. |
4614 if (executableElt.enclosingElement != null && | 4486 if (executableElt.enclosingElement != null && |
(...skipping 27 matching lines...) Expand all Loading... |
4642 // Some element was found in the superclass chain that matches the name | 4514 // Some element was found in the superclass chain that matches the name |
4643 // of the required member. | 4515 // of the required member. |
4644 // If it is not abstract and it is the correct one (types match- the | 4516 // If it is not abstract and it is the correct one (types match- the |
4645 // version of this method that we have has the correct number of | 4517 // version of this method that we have has the correct number of |
4646 // parameters, etc), then this class has a valid implementation of this | 4518 // parameters, etc), then this class has a valid implementation of this |
4647 // method, so skip it. | 4519 // method, so skip it. |
4648 if ((elt is MethodElement && !elt.isAbstract) || | 4520 if ((elt is MethodElement && !elt.isAbstract) || |
4649 (elt is PropertyAccessorElement && !elt.isAbstract)) { | 4521 (elt is PropertyAccessorElement && !elt.isAbstract)) { |
4650 // Since we are comparing two function types, we need to do the | 4522 // Since we are comparing two function types, we need to do the |
4651 // appropriate type substitutions first (). | 4523 // appropriate type substitutions first (). |
4652 FunctionType foundConcreteFT = | 4524 FunctionType foundConcreteFT = _inheritanceManager |
4653 _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance
( | 4525 .substituteTypeArgumentsInMemberFromInheritance( |
4654 concreteType, | 4526 concreteType, memberName, enclosingType); |
4655 memberName, | 4527 FunctionType requiredMemberFT = _inheritanceManager |
4656 enclosingType); | 4528 .substituteTypeArgumentsInMemberFromInheritance( |
4657 FunctionType requiredMemberFT = | 4529 requiredMemberType, memberName, enclosingType); |
4658 _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance
( | |
4659 requiredMemberType, | |
4660 memberName, | |
4661 enclosingType); | |
4662 if (foundConcreteFT.isSubtypeOf(requiredMemberFT)) { | 4530 if (foundConcreteFT.isSubtypeOf(requiredMemberFT)) { |
4663 continue; | 4531 continue; |
4664 } | 4532 } |
4665 } | 4533 } |
4666 } | 4534 } |
4667 // The not qualifying concrete executable element was found, add it to the | 4535 // The not qualifying concrete executable element was found, add it to the |
4668 // list. | 4536 // list. |
4669 missingOverrides.add(executableElt); | 4537 missingOverrides.add(executableElt); |
4670 } | 4538 } |
4671 // Now that we have the set of missing overrides, generate a warning on this | 4539 // Now that we have the set of missing overrides, generate a warning on this |
(...skipping 26 matching lines...) Expand all Loading... |
4698 } else { | 4566 } else { |
4699 newStrMember = "$prefix'${missingOverridesArray[i].displayName}'"; | 4567 newStrMember = "$prefix'${missingOverridesArray[i].displayName}'"; |
4700 } | 4568 } |
4701 stringMembersArrayListSet.add(newStrMember); | 4569 stringMembersArrayListSet.add(newStrMember); |
4702 } | 4570 } |
4703 List<String> stringMembersArray = new List.from(stringMembersArrayListSet); | 4571 List<String> stringMembersArray = new List.from(stringMembersArrayListSet); |
4704 AnalysisErrorWithProperties analysisError; | 4572 AnalysisErrorWithProperties analysisError; |
4705 if (stringMembersArray.length == 1) { | 4573 if (stringMembersArray.length == 1) { |
4706 analysisError = _errorReporter.newErrorWithProperties( | 4574 analysisError = _errorReporter.newErrorWithProperties( |
4707 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, | 4575 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, |
4708 classNameNode, | 4576 classNameNode, [stringMembersArray[0]]); |
4709 [stringMembersArray[0]]); | |
4710 } else if (stringMembersArray.length == 2) { | 4577 } else if (stringMembersArray.length == 2) { |
4711 analysisError = _errorReporter.newErrorWithProperties( | 4578 analysisError = _errorReporter.newErrorWithProperties( |
4712 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, | 4579 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, |
4713 classNameNode, | 4580 classNameNode, [stringMembersArray[0], stringMembersArray[1]]); |
4714 [stringMembersArray[0], stringMembersArray[1]]); | |
4715 } else if (stringMembersArray.length == 3) { | 4581 } else if (stringMembersArray.length == 3) { |
4716 analysisError = _errorReporter.newErrorWithProperties( | 4582 analysisError = _errorReporter.newErrorWithProperties( |
4717 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, | 4583 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, |
4718 classNameNode, | 4584 classNameNode, [ |
4719 [stringMembersArray[0], stringMembersArray[1], stringMembersArray[2]])
; | 4585 stringMembersArray[0], |
| 4586 stringMembersArray[1], |
| 4587 stringMembersArray[2] |
| 4588 ]); |
4720 } else if (stringMembersArray.length == 4) { | 4589 } else if (stringMembersArray.length == 4) { |
4721 analysisError = _errorReporter.newErrorWithProperties( | 4590 analysisError = _errorReporter.newErrorWithProperties( |
4722 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, | 4591 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, |
4723 classNameNode, | 4592 classNameNode, [ |
4724 [ | 4593 stringMembersArray[0], |
4725 stringMembersArray[0], | 4594 stringMembersArray[1], |
4726 stringMembersArray[1], | 4595 stringMembersArray[2], |
4727 stringMembersArray[2], | 4596 stringMembersArray[3] |
4728 stringMembersArray[3]]); | 4597 ]); |
4729 } else { | 4598 } else { |
4730 analysisError = _errorReporter.newErrorWithProperties( | 4599 analysisError = _errorReporter.newErrorWithProperties( |
4731 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLU
S, | 4600 StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLU
S, |
4732 classNameNode, | 4601 classNameNode, [ |
4733 [ | 4602 stringMembersArray[0], |
4734 stringMembersArray[0], | 4603 stringMembersArray[1], |
4735 stringMembersArray[1], | 4604 stringMembersArray[2], |
4736 stringMembersArray[2], | 4605 stringMembersArray[3], |
4737 stringMembersArray[3], | 4606 stringMembersArray.length - 4 |
4738 stringMembersArray.length - 4]); | 4607 ]); |
4739 } | 4608 } |
4740 analysisError.setProperty( | 4609 analysisError.setProperty( |
4741 ErrorProperty.UNIMPLEMENTED_METHODS, | 4610 ErrorProperty.UNIMPLEMENTED_METHODS, missingOverridesArray); |
4742 missingOverridesArray); | |
4743 _errorReporter.reportError(analysisError); | 4611 _errorReporter.reportError(analysisError); |
4744 return true; | 4612 return true; |
4745 } | 4613 } |
4746 | 4614 |
4747 /** | 4615 /** |
4748 * Checks to ensure that the expressions that need to be of type bool, are. Ot
herwise an error is | 4616 * Checks to ensure that the expressions that need to be of type bool, are. Ot
herwise an error is |
4749 * reported on the expression. | 4617 * reported on the expression. |
4750 * | 4618 * |
4751 * @param condition the conditional expression to test | 4619 * @param condition the conditional expression to test |
4752 * @return `true` if and only if an error code is generated on the passed node | 4620 * @return `true` if and only if an error code is generated on the passed node |
4753 * See [StaticTypeWarningCode.NON_BOOL_CONDITION]. | 4621 * See [StaticTypeWarningCode.NON_BOOL_CONDITION]. |
4754 */ | 4622 */ |
4755 bool _checkForNonBoolCondition(Expression condition) { | 4623 bool _checkForNonBoolCondition(Expression condition) { |
4756 DartType conditionType = getStaticType(condition); | 4624 DartType conditionType = getStaticType(condition); |
4757 if (conditionType != null && !conditionType.isAssignableTo(_boolType)) { | 4625 if (conditionType != null && !conditionType.isAssignableTo(_boolType)) { |
4758 _errorReporter.reportErrorForNode( | 4626 _errorReporter.reportErrorForNode( |
4759 StaticTypeWarningCode.NON_BOOL_CONDITION, | 4627 StaticTypeWarningCode.NON_BOOL_CONDITION, condition); |
4760 condition); | |
4761 return true; | 4628 return true; |
4762 } | 4629 } |
4763 return false; | 4630 return false; |
4764 } | 4631 } |
4765 | 4632 |
4766 /** | 4633 /** |
4767 * This verifies that the passed assert statement has either a 'bool' or '() -
> bool' input. | 4634 * This verifies that the passed assert statement has either a 'bool' or '() -
> bool' input. |
4768 * | 4635 * |
4769 * @param node the assert statement to evaluate | 4636 * @param node the assert statement to evaluate |
4770 * @return `true` if and only if an error code is generated on the passed node | 4637 * @return `true` if and only if an error code is generated on the passed node |
4771 * See [StaticTypeWarningCode.NON_BOOL_EXPRESSION]. | 4638 * See [StaticTypeWarningCode.NON_BOOL_EXPRESSION]. |
4772 */ | 4639 */ |
4773 bool _checkForNonBoolExpression(AssertStatement node) { | 4640 bool _checkForNonBoolExpression(AssertStatement node) { |
4774 Expression expression = node.condition; | 4641 Expression expression = node.condition; |
4775 DartType type = getStaticType(expression); | 4642 DartType type = getStaticType(expression); |
4776 if (type is InterfaceType) { | 4643 if (type is InterfaceType) { |
4777 if (!type.isAssignableTo(_boolType)) { | 4644 if (!type.isAssignableTo(_boolType)) { |
4778 _errorReporter.reportErrorForNode( | 4645 _errorReporter.reportErrorForNode( |
4779 StaticTypeWarningCode.NON_BOOL_EXPRESSION, | 4646 StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression); |
4780 expression); | |
4781 return true; | 4647 return true; |
4782 } | 4648 } |
4783 } else if (type is FunctionType) { | 4649 } else if (type is FunctionType) { |
4784 FunctionType functionType = type; | 4650 FunctionType functionType = type; |
4785 if (functionType.typeArguments.length == 0 && | 4651 if (functionType.typeArguments.length == 0 && |
4786 !functionType.returnType.isAssignableTo(_boolType)) { | 4652 !functionType.returnType.isAssignableTo(_boolType)) { |
4787 _errorReporter.reportErrorForNode( | 4653 _errorReporter.reportErrorForNode( |
4788 StaticTypeWarningCode.NON_BOOL_EXPRESSION, | 4654 StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression); |
4789 expression); | |
4790 return true; | 4655 return true; |
4791 } | 4656 } |
4792 } | 4657 } |
4793 return false; | 4658 return false; |
4794 } | 4659 } |
4795 | 4660 |
4796 /** | 4661 /** |
4797 * Checks to ensure that the given expression is assignable to bool. | 4662 * Checks to ensure that the given expression is assignable to bool. |
4798 * | 4663 * |
4799 * @param expression the expression expression to test | 4664 * @param expression the expression expression to test |
4800 * @return `true` if and only if an error code is generated on the passed node | 4665 * @return `true` if and only if an error code is generated on the passed node |
4801 * See [StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION]. | 4666 * See [StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION]. |
4802 */ | 4667 */ |
4803 bool _checkForNonBoolNegationExpression(Expression expression) { | 4668 bool _checkForNonBoolNegationExpression(Expression expression) { |
4804 DartType conditionType = getStaticType(expression); | 4669 DartType conditionType = getStaticType(expression); |
4805 if (conditionType != null && !conditionType.isAssignableTo(_boolType)) { | 4670 if (conditionType != null && !conditionType.isAssignableTo(_boolType)) { |
4806 _errorReporter.reportErrorForNode( | 4671 _errorReporter.reportErrorForNode( |
4807 StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, | 4672 StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression); |
4808 expression); | |
4809 return true; | 4673 return true; |
4810 } | 4674 } |
4811 return false; | 4675 return false; |
4812 } | 4676 } |
4813 | 4677 |
4814 /** | 4678 /** |
4815 * This verifies the passed map literal either: | 4679 * This verifies the passed map literal either: |
4816 * * has `const modifier` | 4680 * * has `const modifier` |
4817 * * has explicit type arguments | 4681 * * has explicit type arguments |
4818 * * is not start of the statement | 4682 * * is not start of the statement |
(...skipping 16 matching lines...) Expand all Loading... |
4835 node.getAncestor((node) => node is ExpressionStatement); | 4699 node.getAncestor((node) => node is ExpressionStatement); |
4836 if (statement == null) { | 4700 if (statement == null) { |
4837 return false; | 4701 return false; |
4838 } | 4702 } |
4839 // OK, statement does not start with map | 4703 // OK, statement does not start with map |
4840 if (!identical(statement.beginToken, node.beginToken)) { | 4704 if (!identical(statement.beginToken, node.beginToken)) { |
4841 return false; | 4705 return false; |
4842 } | 4706 } |
4843 // report problem | 4707 // report problem |
4844 _errorReporter.reportErrorForNode( | 4708 _errorReporter.reportErrorForNode( |
4845 CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, | 4709 CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, node); |
4846 node); | |
4847 return true; | 4710 return true; |
4848 } | 4711 } |
4849 | 4712 |
4850 /** | 4713 /** |
4851 * This verifies the passed method declaration of operator `[]=`, has `void` r
eturn | 4714 * This verifies the passed method declaration of operator `[]=`, has `void` r
eturn |
4852 * type. | 4715 * type. |
4853 * | 4716 * |
4854 * @param node the method declaration to evaluate | 4717 * @param node the method declaration to evaluate |
4855 * @return `true` if and only if an error code is generated on the passed node | 4718 * @return `true` if and only if an error code is generated on the passed node |
4856 * See [StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR]. | 4719 * See [StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR]. |
4857 */ | 4720 */ |
4858 bool _checkForNonVoidReturnTypeForOperator(MethodDeclaration node) { | 4721 bool _checkForNonVoidReturnTypeForOperator(MethodDeclaration node) { |
4859 // check that []= operator | 4722 // check that []= operator |
4860 SimpleIdentifier name = node.name; | 4723 SimpleIdentifier name = node.name; |
4861 if (name.name != "[]=") { | 4724 if (name.name != "[]=") { |
4862 return false; | 4725 return false; |
4863 } | 4726 } |
4864 // check return type | 4727 // check return type |
4865 TypeName typeName = node.returnType; | 4728 TypeName typeName = node.returnType; |
4866 if (typeName != null) { | 4729 if (typeName != null) { |
4867 DartType type = typeName.type; | 4730 DartType type = typeName.type; |
4868 if (type != null && !type.isVoid) { | 4731 if (type != null && !type.isVoid) { |
4869 _errorReporter.reportErrorForNode( | 4732 _errorReporter.reportErrorForNode( |
4870 StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, | 4733 StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, typeName); |
4871 typeName); | |
4872 } | 4734 } |
4873 } | 4735 } |
4874 // no warning | 4736 // no warning |
4875 return false; | 4737 return false; |
4876 } | 4738 } |
4877 | 4739 |
4878 /** | 4740 /** |
4879 * This verifies the passed setter has no return type or the `void` return typ
e. | 4741 * This verifies the passed setter has no return type or the `void` return typ
e. |
4880 * | 4742 * |
4881 * @param typeName the type name to evaluate | 4743 * @param typeName the type name to evaluate |
4882 * @return `true` if and only if an error code is generated on the passed node | 4744 * @return `true` if and only if an error code is generated on the passed node |
4883 * See [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER]. | 4745 * See [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER]. |
4884 */ | 4746 */ |
4885 bool _checkForNonVoidReturnTypeForSetter(TypeName typeName) { | 4747 bool _checkForNonVoidReturnTypeForSetter(TypeName typeName) { |
4886 if (typeName != null) { | 4748 if (typeName != null) { |
4887 DartType type = typeName.type; | 4749 DartType type = typeName.type; |
4888 if (type != null && !type.isVoid) { | 4750 if (type != null && !type.isVoid) { |
4889 _errorReporter.reportErrorForNode( | 4751 _errorReporter.reportErrorForNode( |
4890 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, | 4752 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, typeName); |
4891 typeName); | |
4892 } | 4753 } |
4893 } | 4754 } |
4894 return false; | 4755 return false; |
4895 } | 4756 } |
4896 | 4757 |
4897 /** | 4758 /** |
4898 * This verifies the passed operator-method declaration, does not have an opti
onal parameter. | 4759 * This verifies the passed operator-method declaration, does not have an opti
onal parameter. |
4899 * | 4760 * |
4900 * This method assumes that the method declaration was tested to be an operato
r declaration before | 4761 * This method assumes that the method declaration was tested to be an operato
r declaration before |
4901 * being called. | 4762 * being called. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4934 if (node.kind != ParameterKind.NAMED) { | 4795 if (node.kind != ParameterKind.NAMED) { |
4935 return false; | 4796 return false; |
4936 } | 4797 } |
4937 // name should start with '_' | 4798 // name should start with '_' |
4938 SimpleIdentifier name = node.identifier; | 4799 SimpleIdentifier name = node.identifier; |
4939 if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) { | 4800 if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) { |
4940 return false; | 4801 return false; |
4941 } | 4802 } |
4942 // report problem | 4803 // report problem |
4943 _errorReporter.reportErrorForNode( | 4804 _errorReporter.reportErrorForNode( |
4944 CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, | 4805 CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, node); |
4945 node); | |
4946 return true; | 4806 return true; |
4947 } | 4807 } |
4948 | 4808 |
4949 /** | 4809 /** |
4950 * This checks if the passed constructor declaration is the redirecting genera
tive constructor and | 4810 * This checks if the passed constructor declaration is the redirecting genera
tive constructor and |
4951 * references itself directly or indirectly. | 4811 * references itself directly or indirectly. |
4952 * | 4812 * |
4953 * @param node the constructor declaration to evaluate | 4813 * @param node the constructor declaration to evaluate |
4954 * @param constructorElement the constructor element | 4814 * @param constructorElement the constructor element |
4955 * @return `true` if and only if an error code is generated on the passed node | 4815 * @return `true` if and only if an error code is generated on the passed node |
4956 * See [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]. | 4816 * See [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]. |
4957 */ | 4817 */ |
4958 bool _checkForRecursiveConstructorRedirect(ConstructorDeclaration node, | 4818 bool _checkForRecursiveConstructorRedirect( |
4959 ConstructorElement constructorElement) { | 4819 ConstructorDeclaration node, ConstructorElement constructorElement) { |
4960 // we check generative constructor here | 4820 // we check generative constructor here |
4961 if (node.factoryKeyword != null) { | 4821 if (node.factoryKeyword != null) { |
4962 return false; | 4822 return false; |
4963 } | 4823 } |
4964 // try to find redirecting constructor invocation and analyzer it for | 4824 // try to find redirecting constructor invocation and analyzer it for |
4965 // recursion | 4825 // recursion |
4966 for (ConstructorInitializer initializer in node.initializers) { | 4826 for (ConstructorInitializer initializer in node.initializers) { |
4967 if (initializer is RedirectingConstructorInvocation) { | 4827 if (initializer is RedirectingConstructorInvocation) { |
4968 // OK if no cycle | 4828 // OK if no cycle |
4969 if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) { | 4829 if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) { |
4970 return false; | 4830 return false; |
4971 } | 4831 } |
4972 // report error | 4832 // report error |
4973 _errorReporter.reportErrorForNode( | 4833 _errorReporter.reportErrorForNode( |
4974 CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, | 4834 CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer); |
4975 initializer); | |
4976 return true; | 4835 return true; |
4977 } | 4836 } |
4978 } | 4837 } |
4979 // OK, no redirecting constructor invocation | 4838 // OK, no redirecting constructor invocation |
4980 return false; | 4839 return false; |
4981 } | 4840 } |
4982 | 4841 |
4983 /** | 4842 /** |
4984 * This checks if the passed constructor declaration has redirected constructo
r and references | 4843 * This checks if the passed constructor declaration has redirected constructo
r and references |
4985 * itself directly or indirectly. | 4844 * itself directly or indirectly. |
4986 * | 4845 * |
4987 * @param node the constructor declaration to evaluate | 4846 * @param node the constructor declaration to evaluate |
4988 * @param constructorElement the constructor element | 4847 * @param constructorElement the constructor element |
4989 * @return `true` if and only if an error code is generated on the passed node | 4848 * @return `true` if and only if an error code is generated on the passed node |
4990 * See [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]. | 4849 * See [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]. |
4991 */ | 4850 */ |
4992 bool _checkForRecursiveFactoryRedirect(ConstructorDeclaration node, | 4851 bool _checkForRecursiveFactoryRedirect( |
4993 ConstructorElement constructorElement) { | 4852 ConstructorDeclaration node, ConstructorElement constructorElement) { |
4994 // prepare redirected constructor | 4853 // prepare redirected constructor |
4995 ConstructorName redirectedConstructorNode = node.redirectedConstructor; | 4854 ConstructorName redirectedConstructorNode = node.redirectedConstructor; |
4996 if (redirectedConstructorNode == null) { | 4855 if (redirectedConstructorNode == null) { |
4997 return false; | 4856 return false; |
4998 } | 4857 } |
4999 // OK if no cycle | 4858 // OK if no cycle |
5000 if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) { | 4859 if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) { |
5001 return false; | 4860 return false; |
5002 } | 4861 } |
5003 // report error | 4862 // report error |
(...skipping 10 matching lines...) Expand all Loading... |
5014 * @return `true` if and only if an error code is generated on the passed elem
ent | 4873 * @return `true` if and only if an error code is generated on the passed elem
ent |
5015 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], | 4874 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], |
5016 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], a
nd | 4875 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], a
nd |
5017 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]
. | 4876 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]
. |
5018 */ | 4877 */ |
5019 bool _checkForRecursiveInterfaceInheritance(ClassElement classElt) { | 4878 bool _checkForRecursiveInterfaceInheritance(ClassElement classElt) { |
5020 if (classElt == null) { | 4879 if (classElt == null) { |
5021 return false; | 4880 return false; |
5022 } | 4881 } |
5023 return _safeCheckForRecursiveInterfaceInheritance( | 4882 return _safeCheckForRecursiveInterfaceInheritance( |
5024 classElt, | 4883 classElt, new List<ClassElement>()); |
5025 new List<ClassElement>()); | |
5026 } | 4884 } |
5027 | 4885 |
5028 /** | 4886 /** |
5029 * This checks the passed constructor declaration has a valid combination of r
edirected | 4887 * This checks the passed constructor declaration has a valid combination of r
edirected |
5030 * constructor invocation(s), super constructor invocations and field initiali
zers. | 4888 * constructor invocation(s), super constructor invocations and field initiali
zers. |
5031 * | 4889 * |
5032 * @param node the constructor declaration to evaluate | 4890 * @param node the constructor declaration to evaluate |
5033 * @return `true` if and only if an error code is generated on the passed node | 4891 * @return `true` if and only if an error code is generated on the passed node |
5034 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR]
, | 4892 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR]
, |
5035 * [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR], | 4893 * [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR], |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5068 RedirectingConstructorInvocation invocation = initializer; | 4926 RedirectingConstructorInvocation invocation = initializer; |
5069 ConstructorElement redirectingElement = invocation.staticElement; | 4927 ConstructorElement redirectingElement = invocation.staticElement; |
5070 if (redirectingElement == null) { | 4928 if (redirectingElement == null) { |
5071 String enclosingTypeName = _enclosingClass.displayName; | 4929 String enclosingTypeName = _enclosingClass.displayName; |
5072 String constructorStrName = enclosingTypeName; | 4930 String constructorStrName = enclosingTypeName; |
5073 if (invocation.constructorName != null) { | 4931 if (invocation.constructorName != null) { |
5074 constructorStrName += ".${invocation.constructorName.name}"; | 4932 constructorStrName += ".${invocation.constructorName.name}"; |
5075 } | 4933 } |
5076 _errorReporter.reportErrorForNode( | 4934 _errorReporter.reportErrorForNode( |
5077 CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR, | 4935 CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR, |
5078 invocation, | 4936 invocation, [constructorStrName, enclosingTypeName]); |
5079 [constructorStrName, enclosingTypeName]); | |
5080 } else { | 4937 } else { |
5081 if (redirectingElement.isFactory) { | 4938 if (redirectingElement.isFactory) { |
5082 _errorReporter.reportErrorForNode( | 4939 _errorReporter.reportErrorForNode( |
5083 CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CON
STRUCTOR, | 4940 CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CON
STRUCTOR, |
5084 initializer); | 4941 initializer); |
5085 } | 4942 } |
5086 } | 4943 } |
5087 } | 4944 } |
5088 numRedirections++; | 4945 numRedirections++; |
5089 } | 4946 } |
(...skipping 21 matching lines...) Expand all Loading... |
5111 | 4968 |
5112 /** | 4969 /** |
5113 * This checks if the passed constructor declaration has redirected constructo
r and references | 4970 * This checks if the passed constructor declaration has redirected constructo
r and references |
5114 * itself directly or indirectly. | 4971 * itself directly or indirectly. |
5115 * | 4972 * |
5116 * @param node the constructor declaration to evaluate | 4973 * @param node the constructor declaration to evaluate |
5117 * @param constructorElement the constructor element | 4974 * @param constructorElement the constructor element |
5118 * @return `true` if and only if an error code is generated on the passed node | 4975 * @return `true` if and only if an error code is generated on the passed node |
5119 * See [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]. | 4976 * See [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]. |
5120 */ | 4977 */ |
5121 bool _checkForRedirectToNonConstConstructor(ConstructorDeclaration node, | 4978 bool _checkForRedirectToNonConstConstructor( |
5122 ConstructorElement constructorElement) { | 4979 ConstructorDeclaration node, ConstructorElement constructorElement) { |
5123 // prepare redirected constructor | 4980 // prepare redirected constructor |
5124 ConstructorName redirectedConstructorNode = node.redirectedConstructor; | 4981 ConstructorName redirectedConstructorNode = node.redirectedConstructor; |
5125 if (redirectedConstructorNode == null) { | 4982 if (redirectedConstructorNode == null) { |
5126 return false; | 4983 return false; |
5127 } | 4984 } |
5128 // prepare element | 4985 // prepare element |
5129 if (constructorElement == null) { | 4986 if (constructorElement == null) { |
5130 return false; | 4987 return false; |
5131 } | 4988 } |
5132 // OK, it is not 'const' | 4989 // OK, it is not 'const' |
(...skipping 20 matching lines...) Expand all Loading... |
5153 /** | 5010 /** |
5154 * This checks that the rethrow is inside of a catch clause. | 5011 * This checks that the rethrow is inside of a catch clause. |
5155 * | 5012 * |
5156 * @param node the rethrow expression to evaluate | 5013 * @param node the rethrow expression to evaluate |
5157 * @return `true` if and only if an error code is generated on the passed node | 5014 * @return `true` if and only if an error code is generated on the passed node |
5158 * See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]. | 5015 * See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]. |
5159 */ | 5016 */ |
5160 bool _checkForRethrowOutsideCatch(RethrowExpression node) { | 5017 bool _checkForRethrowOutsideCatch(RethrowExpression node) { |
5161 if (!_isInCatchClause) { | 5018 if (!_isInCatchClause) { |
5162 _errorReporter.reportErrorForNode( | 5019 _errorReporter.reportErrorForNode( |
5163 CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, | 5020 CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, node); |
5164 node); | |
5165 return true; | 5021 return true; |
5166 } | 5022 } |
5167 return false; | 5023 return false; |
5168 } | 5024 } |
5169 | 5025 |
5170 /** | 5026 /** |
5171 * This checks that if the the given constructor declaration is generative, th
en it does not have | 5027 * This checks that if the the given constructor declaration is generative, th
en it does not have |
5172 * an expression function body. | 5028 * an expression function body. |
5173 * | 5029 * |
5174 * @param node the constructor to evaluate | 5030 * @param node the constructor to evaluate |
5175 * @return `true` if and only if an error code is generated on the passed node | 5031 * @return `true` if and only if an error code is generated on the passed node |
5176 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]. | 5032 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]. |
5177 */ | 5033 */ |
5178 bool _checkForReturnInGenerativeConstructor(ConstructorDeclaration node) { | 5034 bool _checkForReturnInGenerativeConstructor(ConstructorDeclaration node) { |
5179 // ignore factory | 5035 // ignore factory |
5180 if (node.factoryKeyword != null) { | 5036 if (node.factoryKeyword != null) { |
5181 return false; | 5037 return false; |
5182 } | 5038 } |
5183 // block body (with possible return statement) is checked elsewhere | 5039 // block body (with possible return statement) is checked elsewhere |
5184 FunctionBody body = node.body; | 5040 FunctionBody body = node.body; |
5185 if (body is! ExpressionFunctionBody) { | 5041 if (body is! ExpressionFunctionBody) { |
5186 return false; | 5042 return false; |
5187 } | 5043 } |
5188 // report error | 5044 // report error |
5189 _errorReporter.reportErrorForNode( | 5045 _errorReporter.reportErrorForNode( |
5190 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, | 5046 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body); |
5191 body); | |
5192 return true; | 5047 return true; |
5193 } | 5048 } |
5194 | 5049 |
5195 /** | 5050 /** |
5196 * This checks that a type mis-match between the return type and the expressed
return type by the | 5051 * This checks that a type mis-match between the return type and the expressed
return type by the |
5197 * enclosing method or function. | 5052 * enclosing method or function. |
5198 * | 5053 * |
5199 * This method is called both by [checkForAllReturnStatementErrorCodes] | 5054 * This method is called both by [checkForAllReturnStatementErrorCodes] |
5200 * and [visitExpressionFunctionBody]. | 5055 * and [visitExpressionFunctionBody]. |
5201 * | 5056 * |
5202 * @param returnExpression the returned expression to evaluate | 5057 * @param returnExpression the returned expression to evaluate |
5203 * @param expectedReturnType the expressed return type by the enclosing method
or function | 5058 * @param expectedReturnType the expressed return type by the enclosing method
or function |
5204 * @return `true` if and only if an error code is generated on the passed node | 5059 * @return `true` if and only if an error code is generated on the passed node |
5205 * See [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. | 5060 * See [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. |
5206 */ | 5061 */ |
5207 bool _checkForReturnOfInvalidType(Expression returnExpression, | 5062 bool _checkForReturnOfInvalidType( |
5208 DartType expectedReturnType) { | 5063 Expression returnExpression, DartType expectedReturnType) { |
5209 if (_enclosingFunction == null) { | 5064 if (_enclosingFunction == null) { |
5210 return false; | 5065 return false; |
5211 } | 5066 } |
5212 if (_inGenerator) { | 5067 if (_inGenerator) { |
5213 // "return expression;" is disallowed in generators, but this is checked | 5068 // "return expression;" is disallowed in generators, but this is checked |
5214 // elsewhere. Bare "return" is always allowed in generators regardless | 5069 // elsewhere. Bare "return" is always allowed in generators regardless |
5215 // of the return type. So no need to do any further checking. | 5070 // of the return type. So no need to do any further checking. |
5216 return false; | 5071 return false; |
5217 } | 5072 } |
5218 DartType staticReturnType = _computeReturnTypeForMethod(returnExpression); | 5073 DartType staticReturnType = _computeReturnTypeForMethod(returnExpression); |
5219 if (expectedReturnType.isVoid) { | 5074 if (expectedReturnType.isVoid) { |
5220 if (staticReturnType.isVoid || | 5075 if (staticReturnType.isVoid || |
5221 staticReturnType.isDynamic || | 5076 staticReturnType.isDynamic || |
5222 staticReturnType.isBottom) { | 5077 staticReturnType.isBottom) { |
5223 return false; | 5078 return false; |
5224 } | 5079 } |
5225 _errorReporter.reportTypeErrorForNode( | 5080 _errorReporter.reportTypeErrorForNode( |
5226 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, | 5081 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [ |
5227 returnExpression, | 5082 staticReturnType, |
5228 [staticReturnType, expectedReturnType, _enclosingFunction.displayName]
); | 5083 expectedReturnType, |
| 5084 _enclosingFunction.displayName |
| 5085 ]); |
5229 return true; | 5086 return true; |
5230 } | 5087 } |
5231 if (staticReturnType.isAssignableTo(expectedReturnType)) { | 5088 if (staticReturnType.isAssignableTo(expectedReturnType)) { |
5232 return false; | 5089 return false; |
5233 } | 5090 } |
5234 _errorReporter.reportTypeErrorForNode( | 5091 _errorReporter.reportTypeErrorForNode( |
5235 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, | 5092 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [ |
5236 returnExpression, | 5093 staticReturnType, |
5237 [staticReturnType, expectedReturnType, _enclosingFunction.displayName]); | 5094 expectedReturnType, |
| 5095 _enclosingFunction.displayName |
| 5096 ]); |
5238 return true; | 5097 return true; |
5239 // TODO(brianwilkerson) Define a hint corresponding to the warning and | 5098 // TODO(brianwilkerson) Define a hint corresponding to the warning and |
5240 // report it if appropriate. | 5099 // report it if appropriate. |
5241 // Type propagatedReturnType = returnExpression.getPropagatedType(); | 5100 // Type propagatedReturnType = returnExpression.getPropagatedType(); |
5242 // boolean isPropagatedAssignable = propagatedReturnType.isAssignableTo(e
xpectedReturnType); | 5101 // boolean isPropagatedAssignable = propagatedReturnType.isAssignableTo(e
xpectedReturnType); |
5243 // if (isStaticAssignable || isPropagatedAssignable) { | 5102 // if (isStaticAssignable || isPropagatedAssignable) { |
5244 // return false; | 5103 // return false; |
5245 // } | 5104 // } |
5246 // errorReporter.reportTypeErrorForNode( | 5105 // errorReporter.reportTypeErrorForNode( |
5247 // StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, | 5106 // StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, |
5248 // returnExpression, | 5107 // returnExpression, |
5249 // staticReturnType, | 5108 // staticReturnType, |
5250 // expectedReturnType, | 5109 // expectedReturnType, |
5251 // enclosingFunction.getDisplayName()); | 5110 // enclosingFunction.getDisplayName()); |
5252 // return true; | 5111 // return true; |
5253 } | 5112 } |
5254 | 5113 |
5255 /** | 5114 /** |
5256 * This checks the given "typeReference" and that the "name" is not the refere
nce to an instance | 5115 * This checks the given "typeReference" and that the "name" is not the refere
nce to an instance |
5257 * member. | 5116 * member. |
5258 * | 5117 * |
5259 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, | 5118 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, |
5260 * or `null`, aka, the class element of 'C' in 'C.x', see | 5119 * or `null`, aka, the class element of 'C' in 'C.x', see |
5261 * [getTypeReference] | 5120 * [getTypeReference] |
5262 * @param name the accessed name to evaluate | 5121 * @param name the accessed name to evaluate |
5263 * @return `true` if and only if an error code is generated on the passed node | 5122 * @return `true` if and only if an error code is generated on the passed node |
5264 * See [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]. | 5123 * See [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]. |
5265 */ | 5124 */ |
5266 bool _checkForStaticAccessToInstanceMember(ClassElement typeReference, | 5125 bool _checkForStaticAccessToInstanceMember( |
5267 SimpleIdentifier name) { | 5126 ClassElement typeReference, SimpleIdentifier name) { |
5268 // OK, target is not a type | 5127 // OK, target is not a type |
5269 if (typeReference == null) { | 5128 if (typeReference == null) { |
5270 return false; | 5129 return false; |
5271 } | 5130 } |
5272 // prepare member Element | 5131 // prepare member Element |
5273 Element element = name.staticElement; | 5132 Element element = name.staticElement; |
5274 if (element is! ExecutableElement) { | 5133 if (element is! ExecutableElement) { |
5275 return false; | 5134 return false; |
5276 } | 5135 } |
5277 ExecutableElement memberElement = element as ExecutableElement; | 5136 ExecutableElement memberElement = element as ExecutableElement; |
5278 // OK, static | 5137 // OK, static |
5279 if (memberElement.isStatic) { | 5138 if (memberElement.isStatic) { |
5280 return false; | 5139 return false; |
5281 } | 5140 } |
5282 // report problem | 5141 // report problem |
5283 _errorReporter.reportErrorForNode( | 5142 _errorReporter.reportErrorForNode( |
5284 StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, | 5143 StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]); |
5285 name, | |
5286 [name.name]); | |
5287 return true; | 5144 return true; |
5288 } | 5145 } |
5289 | 5146 |
5290 /** | 5147 /** |
5291 * This checks that the type of the passed 'switch' expression is assignable t
o the type of the | 5148 * This checks that the type of the passed 'switch' expression is assignable t
o the type of the |
5292 * 'case' members. | 5149 * 'case' members. |
5293 * | 5150 * |
5294 * @param node the 'switch' statement to evaluate | 5151 * @param node the 'switch' statement to evaluate |
5295 * @return `true` if and only if an error code is generated on the passed node | 5152 * @return `true` if and only if an error code is generated on the passed node |
5296 * See [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE]. | 5153 * See [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE]. |
(...skipping 14 matching lines...) Expand all Loading... |
5311 SwitchCase switchCase = switchMember as SwitchCase; | 5168 SwitchCase switchCase = switchMember as SwitchCase; |
5312 // prepare 'case' type | 5169 // prepare 'case' type |
5313 Expression caseExpression = switchCase.expression; | 5170 Expression caseExpression = switchCase.expression; |
5314 DartType caseType = getStaticType(caseExpression); | 5171 DartType caseType = getStaticType(caseExpression); |
5315 // check types | 5172 // check types |
5316 if (expressionType.isAssignableTo(caseType)) { | 5173 if (expressionType.isAssignableTo(caseType)) { |
5317 return false; | 5174 return false; |
5318 } | 5175 } |
5319 // report problem | 5176 // report problem |
5320 _errorReporter.reportErrorForNode( | 5177 _errorReporter.reportErrorForNode( |
5321 StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE, | 5178 StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE, expression, [ |
5322 expression, | 5179 expressionType, |
5323 [expressionType, caseType]); | 5180 caseType |
| 5181 ]); |
5324 return true; | 5182 return true; |
5325 } | 5183 } |
5326 return false; | 5184 return false; |
5327 } | 5185 } |
5328 | 5186 |
5329 /** | 5187 /** |
5330 * This verifies that the passed function type alias does not reference itself
directly. | 5188 * This verifies that the passed function type alias does not reference itself
directly. |
5331 * | 5189 * |
5332 * @param node the function type alias to evaluate | 5190 * @param node the function type alias to evaluate |
5333 * @return `true` if and only if an error code is generated on the passed node | 5191 * @return `true` if and only if an error code is generated on the passed node |
5334 * See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]. | 5192 * See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]. |
5335 */ | 5193 */ |
5336 bool | 5194 bool _checkForTypeAliasCannotReferenceItself_function( |
5337 _checkForTypeAliasCannotReferenceItself_function(FunctionTypeAlias node) { | 5195 FunctionTypeAlias node) { |
5338 FunctionTypeAliasElement element = node.element; | 5196 FunctionTypeAliasElement element = node.element; |
5339 if (!_hasTypedefSelfReference(element)) { | 5197 if (!_hasTypedefSelfReference(element)) { |
5340 return false; | 5198 return false; |
5341 } | 5199 } |
5342 _errorReporter.reportErrorForNode( | 5200 _errorReporter.reportErrorForNode( |
5343 CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, | 5201 CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, node); |
5344 node); | |
5345 return true; | 5202 return true; |
5346 } | 5203 } |
5347 | 5204 |
5348 /** | 5205 /** |
5349 * This verifies that the passed type name is not a deferred type. | 5206 * This verifies that the passed type name is not a deferred type. |
5350 * | 5207 * |
5351 * @param expression the expression to evaluate | 5208 * @param expression the expression to evaluate |
5352 * @return `true` if and only if an error code is generated on the passed node | 5209 * @return `true` if and only if an error code is generated on the passed node |
5353 * See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS]. | 5210 * See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS]. |
5354 */ | 5211 */ |
5355 bool _checkForTypeAnnotationDeferredClass(TypeName node) { | 5212 bool _checkForTypeAnnotationDeferredClass(TypeName node) { |
5356 if (node != null && node.isDeferred) { | 5213 if (node != null && node.isDeferred) { |
5357 _errorReporter.reportErrorForNode( | 5214 _errorReporter.reportErrorForNode( |
5358 StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, | 5215 StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, node, [node.name]); |
5359 node, | |
5360 [node.name]); | |
5361 } | 5216 } |
5362 return false; | 5217 return false; |
5363 } | 5218 } |
5364 | 5219 |
5365 /** | 5220 /** |
5366 * This verifies that the type arguments in the passed type name are all withi
n their bounds. | 5221 * This verifies that the type arguments in the passed type name are all withi
n their bounds. |
5367 * | 5222 * |
5368 * @param node the [TypeName] to evaluate | 5223 * @param node the [TypeName] to evaluate |
5369 * @return `true` if and only if an error code is generated on the passed node | 5224 * @return `true` if and only if an error code is generated on the passed node |
5370 * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]. | 5225 * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5403 boundType = boundType.substitute2(typeArguments, typeParameters); | 5258 boundType = boundType.substitute2(typeArguments, typeParameters); |
5404 } | 5259 } |
5405 if (!argType.isSubtypeOf(boundType)) { | 5260 if (!argType.isSubtypeOf(boundType)) { |
5406 ErrorCode errorCode; | 5261 ErrorCode errorCode; |
5407 if (_isInConstInstanceCreation) { | 5262 if (_isInConstInstanceCreation) { |
5408 errorCode = CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS; | 5263 errorCode = CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS; |
5409 } else { | 5264 } else { |
5410 errorCode = StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS; | 5265 errorCode = StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS; |
5411 } | 5266 } |
5412 _errorReporter.reportTypeErrorForNode( | 5267 _errorReporter.reportTypeErrorForNode( |
5413 errorCode, | 5268 errorCode, argTypeName, [argType, boundType]); |
5414 argTypeName, | |
5415 [argType, boundType]); | |
5416 foundError = true; | 5269 foundError = true; |
5417 } | 5270 } |
5418 } | 5271 } |
5419 } | 5272 } |
5420 return foundError; | 5273 return foundError; |
5421 } | 5274 } |
5422 | 5275 |
5423 /** | 5276 /** |
5424 * This checks that if the passed type name is a type parameter being used to
define a static | 5277 * This checks that if the passed type name is a type parameter being used to
define a static |
5425 * member. | 5278 * member. |
5426 * | 5279 * |
5427 * @param node the type name to evaluate | 5280 * @param node the type name to evaluate |
5428 * @return `true` if and only if an error code is generated on the passed node | 5281 * @return `true` if and only if an error code is generated on the passed node |
5429 * See [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]. | 5282 * See [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]. |
5430 */ | 5283 */ |
5431 bool _checkForTypeParameterReferencedByStatic(TypeName node) { | 5284 bool _checkForTypeParameterReferencedByStatic(TypeName node) { |
5432 if (_isInStaticMethod || _isInStaticVariableDeclaration) { | 5285 if (_isInStaticMethod || _isInStaticVariableDeclaration) { |
5433 DartType type = node.type; | 5286 DartType type = node.type; |
5434 if (type is TypeParameterType) { | 5287 if (type is TypeParameterType) { |
5435 _errorReporter.reportErrorForNode( | 5288 _errorReporter.reportErrorForNode( |
5436 StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, | 5289 StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, node); |
5437 node); | |
5438 return true; | 5290 return true; |
5439 } | 5291 } |
5440 } | 5292 } |
5441 return false; | 5293 return false; |
5442 } | 5294 } |
5443 | 5295 |
5444 /** | 5296 /** |
5445 * This checks that if the passed type parameter is a supertype of its bound. | 5297 * This checks that if the passed type parameter is a supertype of its bound. |
5446 * | 5298 * |
5447 * @param node the type parameter to evaluate | 5299 * @param node the type parameter to evaluate |
5448 * @return `true` if and only if an error code is generated on the passed node | 5300 * @return `true` if and only if an error code is generated on the passed node |
5449 * See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND]. | 5301 * See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND]. |
5450 */ | 5302 */ |
5451 bool _checkForTypeParameterSupertypeOfItsBound(TypeParameter node) { | 5303 bool _checkForTypeParameterSupertypeOfItsBound(TypeParameter node) { |
5452 TypeParameterElement element = node.element; | 5304 TypeParameterElement element = node.element; |
5453 // prepare bound | 5305 // prepare bound |
5454 DartType bound = element.bound; | 5306 DartType bound = element.bound; |
5455 if (bound == null) { | 5307 if (bound == null) { |
5456 return false; | 5308 return false; |
5457 } | 5309 } |
5458 // OK, type parameter is not supertype of its bound | 5310 // OK, type parameter is not supertype of its bound |
5459 if (!bound.isMoreSpecificThan(element.type)) { | 5311 if (!bound.isMoreSpecificThan(element.type)) { |
5460 return false; | 5312 return false; |
5461 } | 5313 } |
5462 // report problem | 5314 // report problem |
5463 _errorReporter.reportErrorForNode( | 5315 _errorReporter.reportErrorForNode( |
5464 StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, | 5316 StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, node, [ |
5465 node, | 5317 element.displayName |
5466 [element.displayName]); | 5318 ]); |
5467 return true; | 5319 return true; |
5468 } | 5320 } |
5469 | 5321 |
5470 /** | 5322 /** |
5471 * This checks that if the passed generative constructor has neither an explic
it super constructor | 5323 * This checks that if the passed generative constructor has neither an explic
it super constructor |
5472 * invocation nor a redirecting constructor invocation, that the superclass ha
s a default | 5324 * invocation nor a redirecting constructor invocation, that the superclass ha
s a default |
5473 * generative constructor. | 5325 * generative constructor. |
5474 * | 5326 * |
5475 * @param node the constructor declaration to evaluate | 5327 * @param node the constructor declaration to evaluate |
5476 * @return `true` if and only if an error code is generated on the passed node | 5328 * @return `true` if and only if an error code is generated on the passed node |
5477 * See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT], | 5329 * See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT], |
5478 * [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and | 5330 * [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and |
5479 * [StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]. | 5331 * [StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]. |
5480 */ | 5332 */ |
5481 bool | 5333 bool _checkForUndefinedConstructorInInitializerImplicit( |
5482 _checkForUndefinedConstructorInInitializerImplicit(ConstructorDeclaration
node) { | 5334 ConstructorDeclaration node) { |
5483 if (_enclosingClass == null) { | 5335 if (_enclosingClass == null) { |
5484 return false; | 5336 return false; |
5485 } | 5337 } |
5486 // do nothing if mixin errors have already been reported for this class. | 5338 // do nothing if mixin errors have already been reported for this class. |
5487 ClassElementImpl enclosingClass = _enclosingClass; | 5339 ClassElementImpl enclosingClass = _enclosingClass; |
5488 if (enclosingClass.mixinErrorsReported) { | 5340 if (enclosingClass.mixinErrorsReported) { |
5489 return false; | 5341 return false; |
5490 } | 5342 } |
5491 // | 5343 // |
5492 // Ignore if the constructor is not generative. | 5344 // Ignore if the constructor is not generative. |
(...skipping 18 matching lines...) Expand all Loading... |
5511 InterfaceType superType = _enclosingClass.supertype; | 5363 InterfaceType superType = _enclosingClass.supertype; |
5512 if (superType == null) { | 5364 if (superType == null) { |
5513 return false; | 5365 return false; |
5514 } | 5366 } |
5515 ClassElement superElement = superType.element; | 5367 ClassElement superElement = superType.element; |
5516 ConstructorElement superUnnamedConstructor = | 5368 ConstructorElement superUnnamedConstructor = |
5517 superElement.unnamedConstructor; | 5369 superElement.unnamedConstructor; |
5518 if (superUnnamedConstructor != null) { | 5370 if (superUnnamedConstructor != null) { |
5519 if (superUnnamedConstructor.isFactory) { | 5371 if (superUnnamedConstructor.isFactory) { |
5520 _errorReporter.reportErrorForNode( | 5372 _errorReporter.reportErrorForNode( |
5521 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, | 5373 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.returnType, [ |
5522 node.returnType, | 5374 superUnnamedConstructor |
5523 [superUnnamedConstructor]); | 5375 ]); |
5524 return true; | 5376 return true; |
5525 } | 5377 } |
5526 if (!superUnnamedConstructor.isDefaultConstructor || | 5378 if (!superUnnamedConstructor.isDefaultConstructor || |
5527 !_enclosingClass.isSuperConstructorAccessible(superUnnamedConstructor)
) { | 5379 !_enclosingClass |
| 5380 .isSuperConstructorAccessible(superUnnamedConstructor)) { |
5528 int offset; | 5381 int offset; |
5529 int length; | 5382 int length; |
5530 { | 5383 { |
5531 Identifier returnType = node.returnType; | 5384 Identifier returnType = node.returnType; |
5532 SimpleIdentifier name = node.name; | 5385 SimpleIdentifier name = node.name; |
5533 offset = returnType.offset; | 5386 offset = returnType.offset; |
5534 length = (name != null ? name.end : returnType.end) - offset; | 5387 length = (name != null ? name.end : returnType.end) - offset; |
5535 } | 5388 } |
5536 _errorReporter.reportErrorForOffset( | 5389 _errorReporter.reportErrorForOffset( |
5537 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, | 5390 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, offset, |
5538 offset, | 5391 length, [superType.displayName]); |
5539 length, | |
5540 [superType.displayName]); | |
5541 } | 5392 } |
5542 return false; | 5393 return false; |
5543 } | 5394 } |
5544 _errorReporter.reportErrorForNode( | 5395 _errorReporter.reportErrorForNode( |
5545 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, | 5396 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, |
5546 node.returnType, | 5397 node.returnType, [superElement.name]); |
5547 [superElement.name]); | |
5548 return true; | 5398 return true; |
5549 } | 5399 } |
5550 | 5400 |
5551 /** | 5401 /** |
5552 * This checks that if the given name is a reference to a static member it is
defined in the | 5402 * This checks that if the given name is a reference to a static member it is
defined in the |
5553 * enclosing class rather than in a superclass. | 5403 * enclosing class rather than in a superclass. |
5554 * | 5404 * |
5555 * @param name the name to be evaluated | 5405 * @param name the name to be evaluated |
5556 * @return `true` if and only if an error code is generated on the passed node | 5406 * @return `true` if and only if an error code is generated on the passed node |
5557 * See [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER
]. | 5407 * See [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER
]. |
5558 */ | 5408 */ |
5559 bool | 5409 bool _checkForUnqualifiedReferenceToNonLocalStaticMember( |
5560 _checkForUnqualifiedReferenceToNonLocalStaticMember(SimpleIdentifier name)
{ | 5410 SimpleIdentifier name) { |
5561 Element element = name.staticElement; | 5411 Element element = name.staticElement; |
5562 if (element == null || element is TypeParameterElement) { | 5412 if (element == null || element is TypeParameterElement) { |
5563 return false; | 5413 return false; |
5564 } | 5414 } |
5565 Element enclosingElement = element.enclosingElement; | 5415 Element enclosingElement = element.enclosingElement; |
5566 if (enclosingElement is! ClassElement) { | 5416 if (enclosingElement is! ClassElement) { |
5567 return false; | 5417 return false; |
5568 } | 5418 } |
5569 if ((element is MethodElement && !element.isStatic) || | 5419 if ((element is MethodElement && !element.isStatic) || |
5570 (element is PropertyAccessorElement && !element.isStatic)) { | 5420 (element is PropertyAccessorElement && !element.isStatic)) { |
5571 return false; | 5421 return false; |
5572 } | 5422 } |
5573 if (identical(enclosingElement, _enclosingClass)) { | 5423 if (identical(enclosingElement, _enclosingClass)) { |
5574 return false; | 5424 return false; |
5575 } | 5425 } |
5576 _errorReporter.reportErrorForNode( | 5426 _errorReporter.reportErrorForNode( |
5577 StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, | 5427 StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, |
5578 name, | 5428 name, [name.name]); |
5579 [name.name]); | |
5580 return true; | 5429 return true; |
5581 } | 5430 } |
5582 | 5431 |
5583 void _checkForValidField(FieldFormalParameter node) { | 5432 void _checkForValidField(FieldFormalParameter node) { |
5584 ParameterElement element = node.element; | 5433 ParameterElement element = node.element; |
5585 if (element is FieldFormalParameterElement) { | 5434 if (element is FieldFormalParameterElement) { |
5586 FieldElement fieldElement = element.field; | 5435 FieldElement fieldElement = element.field; |
5587 if (fieldElement == null || fieldElement.isSynthetic) { | 5436 if (fieldElement == null || fieldElement.isSynthetic) { |
5588 _errorReporter.reportErrorForNode( | 5437 _errorReporter.reportErrorForNode( |
5589 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, | 5438 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, |
5590 node, | 5439 node, [node.identifier.name]); |
5591 [node.identifier.name]); | |
5592 } else { | 5440 } else { |
5593 ParameterElement parameterElement = node.element; | 5441 ParameterElement parameterElement = node.element; |
5594 if (parameterElement is FieldFormalParameterElementImpl) { | 5442 if (parameterElement is FieldFormalParameterElementImpl) { |
5595 FieldFormalParameterElementImpl fieldFormal = parameterElement; | 5443 FieldFormalParameterElementImpl fieldFormal = parameterElement; |
5596 DartType declaredType = fieldFormal.type; | 5444 DartType declaredType = fieldFormal.type; |
5597 DartType fieldType = fieldElement.type; | 5445 DartType fieldType = fieldElement.type; |
5598 if (fieldElement.isSynthetic) { | 5446 if (fieldElement.isSynthetic) { |
5599 _errorReporter.reportErrorForNode( | 5447 _errorReporter.reportErrorForNode( |
5600 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, | 5448 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, |
5601 node, | 5449 node, [node.identifier.name]); |
5602 [node.identifier.name]); | |
5603 } else if (fieldElement.isStatic) { | 5450 } else if (fieldElement.isStatic) { |
5604 _errorReporter.reportErrorForNode( | 5451 _errorReporter.reportErrorForNode( |
5605 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, | 5452 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, |
5606 node, | |
5607 [node.identifier.name]); | 5453 [node.identifier.name]); |
5608 } else if (declaredType != null && | 5454 } else if (declaredType != null && |
5609 fieldType != null && | 5455 fieldType != null && |
5610 !declaredType.isAssignableTo(fieldType)) { | 5456 !declaredType.isAssignableTo(fieldType)) { |
5611 _errorReporter.reportTypeErrorForNode( | 5457 _errorReporter.reportTypeErrorForNode( |
5612 StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, | 5458 StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, |
5613 node, | 5459 node, [declaredType, fieldType]); |
5614 [declaredType, fieldType]); | |
5615 } | 5460 } |
5616 } else { | 5461 } else { |
5617 if (fieldElement.isSynthetic) { | 5462 if (fieldElement.isSynthetic) { |
5618 _errorReporter.reportErrorForNode( | 5463 _errorReporter.reportErrorForNode( |
5619 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, | 5464 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, |
5620 node, | 5465 node, [node.identifier.name]); |
5621 [node.identifier.name]); | |
5622 } else if (fieldElement.isStatic) { | 5466 } else if (fieldElement.isStatic) { |
5623 _errorReporter.reportErrorForNode( | 5467 _errorReporter.reportErrorForNode( |
5624 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, | 5468 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, |
5625 node, | |
5626 [node.identifier.name]); | 5469 [node.identifier.name]); |
5627 } | 5470 } |
5628 } | 5471 } |
5629 } | 5472 } |
5630 } | 5473 } |
5631 // else { | 5474 // else { |
5632 // // TODO(jwren) Report error, constructor initializer variable is a top
level element | 5475 // // TODO(jwren) Report error, constructor initializer variable is a top
level element |
5633 // // (Either here or in ErrorVerifier.checkForAllFinalInitializedErrorCo
des) | 5476 // // (Either here or in ErrorVerifier.checkForAllFinalInitializedErrorCo
des) |
5634 // } | 5477 // } |
5635 } | 5478 } |
5636 | 5479 |
5637 /** | 5480 /** |
5638 * This verifies that the given getter does not have a return type of 'void'. | 5481 * This verifies that the given getter does not have a return type of 'void'. |
5639 * | 5482 * |
5640 * @param node the method declaration to evaluate | 5483 * @param node the method declaration to evaluate |
5641 * @return `true` if and only if an error code is generated on the passed node | 5484 * @return `true` if and only if an error code is generated on the passed node |
5642 * See [StaticWarningCode.VOID_RETURN_FOR_GETTER]. | 5485 * See [StaticWarningCode.VOID_RETURN_FOR_GETTER]. |
5643 */ | 5486 */ |
5644 bool _checkForVoidReturnType(MethodDeclaration node) { | 5487 bool _checkForVoidReturnType(MethodDeclaration node) { |
5645 TypeName returnType = node.returnType; | 5488 TypeName returnType = node.returnType; |
5646 if (returnType == null || returnType.name.name != "void") { | 5489 if (returnType == null || returnType.name.name != "void") { |
5647 return false; | 5490 return false; |
5648 } | 5491 } |
5649 _errorReporter.reportErrorForNode( | 5492 _errorReporter.reportErrorForNode( |
5650 StaticWarningCode.VOID_RETURN_FOR_GETTER, | 5493 StaticWarningCode.VOID_RETURN_FOR_GETTER, returnType); |
5651 returnType); | |
5652 return true; | 5494 return true; |
5653 } | 5495 } |
5654 | 5496 |
5655 /** | 5497 /** |
5656 * This verifies the passed operator-method declaration, has correct number of
parameters. | 5498 * This verifies the passed operator-method declaration, has correct number of
parameters. |
5657 * | 5499 * |
5658 * This method assumes that the method declaration was tested to be an operato
r declaration before | 5500 * This method assumes that the method declaration was tested to be an operato
r declaration before |
5659 * being called. | 5501 * being called. |
5660 * | 5502 * |
5661 * @param node the method declaration to evaluate | 5503 * @param node the method declaration to evaluate |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5695 "<<" == name || | 5537 "<<" == name || |
5696 ">>" == name || | 5538 ">>" == name || |
5697 "[]" == name) { | 5539 "[]" == name) { |
5698 expected = 1; | 5540 expected = 1; |
5699 } else if ("~" == name) { | 5541 } else if ("~" == name) { |
5700 expected = 0; | 5542 expected = 0; |
5701 } | 5543 } |
5702 if (expected != -1 && numParameters != expected) { | 5544 if (expected != -1 && numParameters != expected) { |
5703 _errorReporter.reportErrorForNode( | 5545 _errorReporter.reportErrorForNode( |
5704 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR, | 5546 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR, |
5705 nameNode, | 5547 nameNode, [name, expected, numParameters]); |
5706 [name, expected, numParameters]); | |
5707 return true; | 5548 return true; |
5708 } | 5549 } |
5709 // check for operator "-" | 5550 // check for operator "-" |
5710 if ("-" == name && numParameters > 1) { | 5551 if ("-" == name && numParameters > 1) { |
5711 _errorReporter.reportErrorForNode( | 5552 _errorReporter.reportErrorForNode( |
5712 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS, | 5553 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS, |
5713 nameNode, | 5554 nameNode, [numParameters]); |
5714 [numParameters]); | |
5715 return true; | 5555 return true; |
5716 } | 5556 } |
5717 // OK | 5557 // OK |
5718 return false; | 5558 return false; |
5719 } | 5559 } |
5720 | 5560 |
5721 /** | 5561 /** |
5722 * This verifies if the passed setter parameter list have only one required pa
rameter. | 5562 * This verifies if the passed setter parameter list have only one required pa
rameter. |
5723 * | 5563 * |
5724 * This method assumes that the method declaration was tested to be a setter b
efore being called. | 5564 * This method assumes that the method declaration was tested to be a setter b
efore being called. |
5725 * | 5565 * |
5726 * @param setterName the name of the setter to report problems on | 5566 * @param setterName the name of the setter to report problems on |
5727 * @param parameterList the parameter list to evaluate | 5567 * @param parameterList the parameter list to evaluate |
5728 * @return `true` if and only if an error code is generated on the passed node | 5568 * @return `true` if and only if an error code is generated on the passed node |
5729 * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]. | 5569 * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]. |
5730 */ | 5570 */ |
5731 bool _checkForWrongNumberOfParametersForSetter(SimpleIdentifier setterName, | 5571 bool _checkForWrongNumberOfParametersForSetter( |
5732 FormalParameterList parameterList) { | 5572 SimpleIdentifier setterName, FormalParameterList parameterList) { |
5733 if (setterName == null) { | 5573 if (setterName == null) { |
5734 return false; | 5574 return false; |
5735 } | 5575 } |
5736 if (parameterList == null) { | 5576 if (parameterList == null) { |
5737 return false; | 5577 return false; |
5738 } | 5578 } |
5739 NodeList<FormalParameter> parameters = parameterList.parameters; | 5579 NodeList<FormalParameter> parameters = parameterList.parameters; |
5740 if (parameters.length != 1 || | 5580 if (parameters.length != 1 || |
5741 parameters[0].kind != ParameterKind.REQUIRED) { | 5581 parameters[0].kind != ParameterKind.REQUIRED) { |
5742 _errorReporter.reportErrorForNode( | 5582 _errorReporter.reportErrorForNode( |
5743 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, | 5583 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, |
5744 setterName); | 5584 setterName); |
5745 return true; | 5585 return true; |
5746 } | 5586 } |
5747 return false; | 5587 return false; |
5748 } | 5588 } |
5749 | 5589 |
5750 /** | 5590 /** |
5751 * Check for a type mis-match between the yielded type and the declared | 5591 * Check for a type mis-match between the yielded type and the declared |
5752 * return type of a generator function. | 5592 * return type of a generator function. |
5753 * | 5593 * |
5754 * This method should only be called in generator functions. | 5594 * This method should only be called in generator functions. |
5755 */ | 5595 */ |
5756 bool _checkForYieldOfInvalidType(Expression yieldExpression, | 5596 bool _checkForYieldOfInvalidType( |
5757 bool isYieldEach) { | 5597 Expression yieldExpression, bool isYieldEach) { |
5758 assert(_inGenerator); | 5598 assert(_inGenerator); |
5759 if (_enclosingFunction == null) { | 5599 if (_enclosingFunction == null) { |
5760 return false; | 5600 return false; |
5761 } | 5601 } |
5762 DartType declaredReturnType = _enclosingFunction.returnType; | 5602 DartType declaredReturnType = _enclosingFunction.returnType; |
5763 DartType staticYieldedType = getStaticType(yieldExpression); | 5603 DartType staticYieldedType = getStaticType(yieldExpression); |
5764 DartType impliedReturnType; | 5604 DartType impliedReturnType; |
5765 if (isYieldEach) { | 5605 if (isYieldEach) { |
5766 impliedReturnType = staticYieldedType; | 5606 impliedReturnType = staticYieldedType; |
5767 } else if (_enclosingFunction.isAsynchronous) { | 5607 } else if (_enclosingFunction.isAsynchronous) { |
5768 impliedReturnType = | 5608 impliedReturnType = |
5769 _typeProvider.streamType.substitute4(<DartType>[staticYieldedType]); | 5609 _typeProvider.streamType.substitute4(<DartType>[staticYieldedType]); |
5770 } else { | 5610 } else { |
5771 impliedReturnType = | 5611 impliedReturnType = |
5772 _typeProvider.iterableType.substitute4(<DartType>[staticYieldedType]); | 5612 _typeProvider.iterableType.substitute4(<DartType>[staticYieldedType]); |
5773 } | 5613 } |
5774 if (!impliedReturnType.isAssignableTo(declaredReturnType)) { | 5614 if (!impliedReturnType.isAssignableTo(declaredReturnType)) { |
5775 _errorReporter.reportTypeErrorForNode( | 5615 _errorReporter.reportTypeErrorForNode( |
5776 StaticTypeWarningCode.YIELD_OF_INVALID_TYPE, | 5616 StaticTypeWarningCode.YIELD_OF_INVALID_TYPE, yieldExpression, [ |
5777 yieldExpression, | 5617 impliedReturnType, |
5778 [impliedReturnType, declaredReturnType]); | 5618 declaredReturnType |
| 5619 ]); |
5779 return true; | 5620 return true; |
5780 } | 5621 } |
5781 if (isYieldEach) { | 5622 if (isYieldEach) { |
5782 // Since the declared return type might have been "dynamic", we need to | 5623 // Since the declared return type might have been "dynamic", we need to |
5783 // also check that the implied return type is assignable to generic | 5624 // also check that the implied return type is assignable to generic |
5784 // Stream/Iterable. | 5625 // Stream/Iterable. |
5785 DartType requiredReturnType; | 5626 DartType requiredReturnType; |
5786 if (_enclosingFunction.isAsynchronous) { | 5627 if (_enclosingFunction.isAsynchronous) { |
5787 requiredReturnType = _typeProvider.streamDynamicType; | 5628 requiredReturnType = _typeProvider.streamDynamicType; |
5788 } else { | 5629 } else { |
5789 requiredReturnType = _typeProvider.iterableDynamicType; | 5630 requiredReturnType = _typeProvider.iterableDynamicType; |
5790 } | 5631 } |
5791 if (!impliedReturnType.isAssignableTo(requiredReturnType)) { | 5632 if (!impliedReturnType.isAssignableTo(requiredReturnType)) { |
5792 _errorReporter.reportTypeErrorForNode( | 5633 _errorReporter.reportTypeErrorForNode( |
5793 StaticTypeWarningCode.YIELD_OF_INVALID_TYPE, | 5634 StaticTypeWarningCode.YIELD_OF_INVALID_TYPE, yieldExpression, [ |
5794 yieldExpression, | 5635 impliedReturnType, |
5795 [impliedReturnType, requiredReturnType]); | 5636 requiredReturnType |
| 5637 ]); |
5796 return true; | 5638 return true; |
5797 } | 5639 } |
5798 } | 5640 } |
5799 return false; | 5641 return false; |
5800 } | 5642 } |
5801 | 5643 |
5802 /** | 5644 /** |
5803 * This verifies that if the given class declaration implements the class Func
tion that it has a | 5645 * This verifies that if the given class declaration implements the class Func
tion that it has a |
5804 * concrete implementation of the call method. | 5646 * concrete implementation of the call method. |
5805 * | 5647 * |
(...skipping 16 matching lines...) Expand all Loading... |
5822 if (classElement.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME) != | 5664 if (classElement.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME) != |
5823 null) { | 5665 null) { |
5824 return false; | 5666 return false; |
5825 } | 5667 } |
5826 ExecutableElement callMethod = | 5668 ExecutableElement callMethod = |
5827 _inheritanceManager.lookupMember(classElement, "call"); | 5669 _inheritanceManager.lookupMember(classElement, "call"); |
5828 if (callMethod == null || | 5670 if (callMethod == null || |
5829 callMethod is! MethodElement || | 5671 callMethod is! MethodElement || |
5830 (callMethod as MethodElement).isAbstract) { | 5672 (callMethod as MethodElement).isAbstract) { |
5831 _errorReporter.reportErrorForNode( | 5673 _errorReporter.reportErrorForNode( |
5832 StaticWarningCode.FUNCTION_WITHOUT_CALL, | 5674 StaticWarningCode.FUNCTION_WITHOUT_CALL, node.name); |
5833 node.name); | |
5834 return true; | 5675 return true; |
5835 } | 5676 } |
5836 return false; | 5677 return false; |
5837 } | 5678 } |
5838 | 5679 |
5839 /** | 5680 /** |
5840 * This verifies that the given class declaration does not have the same class
in the 'extends' | 5681 * This verifies that the given class declaration does not have the same class
in the 'extends' |
5841 * and 'implements' clauses. | 5682 * and 'implements' clauses. |
5842 * | 5683 * |
5843 * @return `true` if and only if an error code is generated on the passed node | 5684 * @return `true` if and only if an error code is generated on the passed node |
5844 * See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]. | 5685 * See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]. |
5845 */ | 5686 */ |
5846 bool _checkImplementsSuperClass(ClassDeclaration node) { | 5687 bool _checkImplementsSuperClass(ClassDeclaration node) { |
5847 // prepare super type | 5688 // prepare super type |
5848 InterfaceType superType = _enclosingClass.supertype; | 5689 InterfaceType superType = _enclosingClass.supertype; |
5849 if (superType == null) { | 5690 if (superType == null) { |
5850 return false; | 5691 return false; |
5851 } | 5692 } |
5852 // prepare interfaces | 5693 // prepare interfaces |
5853 ImplementsClause implementsClause = node.implementsClause; | 5694 ImplementsClause implementsClause = node.implementsClause; |
5854 if (implementsClause == null) { | 5695 if (implementsClause == null) { |
5855 return false; | 5696 return false; |
5856 } | 5697 } |
5857 // check interfaces | 5698 // check interfaces |
5858 bool hasProblem = false; | 5699 bool hasProblem = false; |
5859 for (TypeName interfaceNode in implementsClause.interfaces) { | 5700 for (TypeName interfaceNode in implementsClause.interfaces) { |
5860 if (interfaceNode.type == superType) { | 5701 if (interfaceNode.type == superType) { |
5861 hasProblem = true; | 5702 hasProblem = true; |
5862 _errorReporter.reportErrorForNode( | 5703 _errorReporter.reportErrorForNode( |
5863 CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, | 5704 CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, interfaceNode, |
5864 interfaceNode, | |
5865 [superType.displayName]); | 5705 [superType.displayName]); |
5866 } | 5706 } |
5867 } | 5707 } |
5868 // done | 5708 // done |
5869 return hasProblem; | 5709 return hasProblem; |
5870 } | 5710 } |
5871 | 5711 |
5872 DartType _computeReturnTypeForMethod(Expression returnExpression) { | 5712 DartType _computeReturnTypeForMethod(Expression returnExpression) { |
5873 // This method should never be called for generators, since generators are | 5713 // This method should never be called for generators, since generators are |
5874 // never allowed to contain return statements with expressions. | 5714 // never allowed to contain return statements with expressions. |
5875 assert(!_inGenerator); | 5715 assert(!_inGenerator); |
5876 if (returnExpression == null) { | 5716 if (returnExpression == null) { |
5877 if (_enclosingFunction.isAsynchronous) { | 5717 if (_enclosingFunction.isAsynchronous) { |
5878 return _typeProvider.futureNullType; | 5718 return _typeProvider.futureNullType; |
5879 } else { | 5719 } else { |
5880 return VoidTypeImpl.instance; | 5720 return VoidTypeImpl.instance; |
5881 } | 5721 } |
5882 } | 5722 } |
5883 DartType staticReturnType = getStaticType(returnExpression); | 5723 DartType staticReturnType = getStaticType(returnExpression); |
5884 if (staticReturnType != null && _enclosingFunction.isAsynchronous) { | 5724 if (staticReturnType != null && _enclosingFunction.isAsynchronous) { |
5885 return _typeProvider.futureType.substitute4( | 5725 return _typeProvider.futureType.substitute4(<DartType>[ |
5886 <DartType>[StaticTypeAnalyzer.flattenFutures(_typeProvider, staticRetu
rnType)]); | 5726 StaticTypeAnalyzer.flattenFutures(_typeProvider, staticReturnType) |
| 5727 ]); |
5887 } | 5728 } |
5888 return staticReturnType; | 5729 return staticReturnType; |
5889 } | 5730 } |
5890 | 5731 |
5891 /** | 5732 /** |
5892 * Return the error code that should be used when the given class references i
tself directly. | 5733 * Return the error code that should be used when the given class references i
tself directly. |
5893 * | 5734 * |
5894 * @param classElt the class that references itself | 5735 * @param classElt the class that references itself |
5895 * @return the error code that should be used | 5736 * @return the error code that should be used |
5896 */ | 5737 */ |
5897 ErrorCode _getBaseCaseErrorCode(ClassElement classElt) { | 5738 ErrorCode _getBaseCaseErrorCode(ClassElement classElt) { |
5898 InterfaceType supertype = classElt.supertype; | 5739 InterfaceType supertype = classElt.supertype; |
5899 if (supertype != null && _enclosingClass == supertype.element) { | 5740 if (supertype != null && _enclosingClass == supertype.element) { |
5900 return | 5741 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTE
NDS; |
5901 CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS
; | |
5902 } | 5742 } |
5903 List<InterfaceType> mixins = classElt.mixins; | 5743 List<InterfaceType> mixins = classElt.mixins; |
5904 for (int i = 0; i < mixins.length; i++) { | 5744 for (int i = 0; i < mixins.length; i++) { |
5905 if (_enclosingClass == mixins[i].element) { | 5745 if (_enclosingClass == mixins[i].element) { |
5906 return | 5746 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WI
TH; |
5907 CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH; | |
5908 } | 5747 } |
5909 } | 5748 } |
5910 return | 5749 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEM
ENTS; |
5911 CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENT
S; | |
5912 } | 5750 } |
5913 | 5751 |
5914 /** | 5752 /** |
5915 * Given an expression in a switch case whose value is expected to be an enum
constant, return the | 5753 * Given an expression in a switch case whose value is expected to be an enum
constant, return the |
5916 * name of the constant. | 5754 * name of the constant. |
5917 * | 5755 * |
5918 * @param expression the expression from the switch case | 5756 * @param expression the expression from the switch case |
5919 * @return the name of the constant referenced by the expression | 5757 * @return the name of the constant referenced by the expression |
5920 */ | 5758 */ |
5921 String _getConstantName(Expression expression) { | 5759 String _getConstantName(Expression expression) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5972 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. | 5810 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. |
5973 */ | 5811 */ |
5974 bool _hasDeferredPrefixCollision(List<ImportDirective> directives) { | 5812 bool _hasDeferredPrefixCollision(List<ImportDirective> directives) { |
5975 bool foundError = false; | 5813 bool foundError = false; |
5976 int count = directives.length; | 5814 int count = directives.length; |
5977 if (count > 1) { | 5815 if (count > 1) { |
5978 for (int i = 0; i < count; i++) { | 5816 for (int i = 0; i < count; i++) { |
5979 sc.Token deferredToken = directives[i].deferredKeyword; | 5817 sc.Token deferredToken = directives[i].deferredKeyword; |
5980 if (deferredToken != null) { | 5818 if (deferredToken != null) { |
5981 _errorReporter.reportErrorForToken( | 5819 _errorReporter.reportErrorForToken( |
5982 CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, | 5820 CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken); |
5983 deferredToken); | |
5984 foundError = true; | 5821 foundError = true; |
5985 } | 5822 } |
5986 } | 5823 } |
5987 } | 5824 } |
5988 return foundError; | 5825 return foundError; |
5989 } | 5826 } |
5990 | 5827 |
5991 /** | 5828 /** |
5992 * @return `true` if the given constructor redirects to itself, directly or in
directly | 5829 * @return `true` if the given constructor redirects to itself, directly or in
directly |
5993 */ | 5830 */ |
(...skipping 14 matching lines...) Expand all Loading... |
6008 } | 5845 } |
6009 | 5846 |
6010 /** | 5847 /** |
6011 * @return <code>true</code> if given [Element] has direct or indirect referen
ce to itself | 5848 * @return <code>true</code> if given [Element] has direct or indirect referen
ce to itself |
6012 * from anywhere except [ClassElement] or type parameter bounds. | 5849 * from anywhere except [ClassElement] or type parameter bounds. |
6013 */ | 5850 */ |
6014 bool _hasTypedefSelfReference(Element target) { | 5851 bool _hasTypedefSelfReference(Element target) { |
6015 Set<Element> checked = new HashSet<Element>(); | 5852 Set<Element> checked = new HashSet<Element>(); |
6016 List<Element> toCheck = new List<Element>(); | 5853 List<Element> toCheck = new List<Element>(); |
6017 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference elementVisi
tor = | 5854 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference elementVisi
tor = |
6018 new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(toC
heck); | 5855 new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference( |
| 5856 toCheck); |
6019 toCheck.add(target); | 5857 toCheck.add(target); |
6020 bool firstIteration = true; | 5858 bool firstIteration = true; |
6021 while (true) { | 5859 while (true) { |
6022 Element current; | 5860 Element current; |
6023 // get next element | 5861 // get next element |
6024 while (true) { | 5862 while (true) { |
6025 // may be no more elements to check | 5863 // may be no more elements to check |
6026 if (toCheck.isEmpty) { | 5864 if (toCheck.isEmpty) { |
6027 return false; | 5865 return false; |
6028 } | 5866 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6065 * its' mixins that is concrete. | 5903 * its' mixins that is concrete. |
6066 * | 5904 * |
6067 * By "match", only the name of the member is tested to match, it does not hav
e to equal or be a | 5905 * By "match", only the name of the member is tested to match, it does not hav
e to equal or be a |
6068 * subtype of the passed executable element, this is due to the specific use w
here this method is | 5906 * subtype of the passed executable element, this is due to the specific use w
here this method is |
6069 * used in [checkForNonAbstractClassInheritsAbstractMember]. | 5907 * used in [checkForNonAbstractClassInheritsAbstractMember]. |
6070 * | 5908 * |
6071 * @param executableElt the executable to search for in the passed class eleme
nt | 5909 * @param executableElt the executable to search for in the passed class eleme
nt |
6072 * @param classElt the class method to search through the members of | 5910 * @param classElt the class method to search through the members of |
6073 * @return `true` iff the passed member is found in the passed class element | 5911 * @return `true` iff the passed member is found in the passed class element |
6074 */ | 5912 */ |
6075 bool _isMemberInClassOrMixin(ExecutableElement executableElt, | 5913 bool _isMemberInClassOrMixin( |
6076 ClassElement classElt) { | 5914 ExecutableElement executableElt, ClassElement classElt) { |
6077 ExecutableElement foundElt = null; | 5915 ExecutableElement foundElt = null; |
6078 String executableName = executableElt.name; | 5916 String executableName = executableElt.name; |
6079 if (executableElt is MethodElement) { | 5917 if (executableElt is MethodElement) { |
6080 foundElt = classElt.getMethod(executableName); | 5918 foundElt = classElt.getMethod(executableName); |
6081 if (foundElt != null && !(foundElt as MethodElement).isAbstract) { | 5919 if (foundElt != null && !(foundElt as MethodElement).isAbstract) { |
6082 return true; | 5920 return true; |
6083 } | 5921 } |
6084 List<InterfaceType> mixins = classElt.mixins; | 5922 List<InterfaceType> mixins = classElt.mixins; |
6085 for (int i = 0; i < mixins.length && foundElt == null; i++) { | 5923 for (int i = 0; i < mixins.length && foundElt == null; i++) { |
6086 foundElt = mixins[i].getMethod(executableName); | 5924 foundElt = mixins[i].getMethod(executableName); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6140 } | 5978 } |
6141 | 5979 |
6142 /** | 5980 /** |
6143 * Return `true` if the given identifier is in a location where it is allowed
to resolve to | 5981 * Return `true` if the given identifier is in a location where it is allowed
to resolve to |
6144 * a static member of a supertype. | 5982 * a static member of a supertype. |
6145 * | 5983 * |
6146 * @param node the node being tested | 5984 * @param node the node being tested |
6147 * @return `true` if the given identifier is in a location where it is allowed
to resolve to | 5985 * @return `true` if the given identifier is in a location where it is allowed
to resolve to |
6148 * a static member of a supertype | 5986 * a static member of a supertype |
6149 */ | 5987 */ |
6150 bool | 5988 bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed( |
6151 _isUnqualifiedReferenceToNonLocalStaticMemberAllowed(SimpleIdentifier node
) { | 5989 SimpleIdentifier node) { |
6152 if (node.inDeclarationContext()) { | 5990 if (node.inDeclarationContext()) { |
6153 return true; | 5991 return true; |
6154 } | 5992 } |
6155 AstNode parent = node.parent; | 5993 AstNode parent = node.parent; |
6156 if (parent is ConstructorName || | 5994 if (parent is ConstructorName || |
6157 parent is MethodInvocation || | 5995 parent is MethodInvocation || |
6158 parent is PropertyAccess || | 5996 parent is PropertyAccess || |
6159 parent is SuperConstructorInvocation) { | 5997 parent is SuperConstructorInvocation) { |
6160 return true; | 5998 return true; |
6161 } | 5999 } |
6162 if (parent is PrefixedIdentifier && identical(parent.identifier, node)) { | 6000 if (parent is PrefixedIdentifier && identical(parent.identifier, node)) { |
6163 return true; | 6001 return true; |
6164 } | 6002 } |
6165 if (parent is Annotation && identical(parent.constructorName, node)) { | 6003 if (parent is Annotation && identical(parent.constructorName, node)) { |
6166 return true; | 6004 return true; |
6167 } | 6005 } |
6168 if (parent is CommentReference) { | 6006 if (parent is CommentReference) { |
6169 CommentReference commentReference = parent; | 6007 CommentReference commentReference = parent; |
6170 if (commentReference.newKeyword != null) { | 6008 if (commentReference.newKeyword != null) { |
6171 return true; | 6009 return true; |
6172 } | 6010 } |
6173 } | 6011 } |
6174 return false; | 6012 return false; |
6175 } | 6013 } |
6176 | 6014 |
6177 bool _isUserDefinedObject(EvaluationResultImpl result) => | 6015 bool _isUserDefinedObject(EvaluationResultImpl result) => result == null || |
6178 result == null || (result.value != null && result.value.isUserDefinedObjec
t); | 6016 (result.value != null && result.value.isUserDefinedObject); |
6179 | 6017 |
6180 /** | 6018 /** |
6181 * This checks the class declaration is not a superinterface to itself. | 6019 * This checks the class declaration is not a superinterface to itself. |
6182 * | 6020 * |
6183 * @param classElt the class element to test | 6021 * @param classElt the class element to test |
6184 * @param path a list containing the potentially cyclic implements path | 6022 * @param path a list containing the potentially cyclic implements path |
6185 * @return `true` if and only if an error code is generated on the passed elem
ent | 6023 * @return `true` if and only if an error code is generated on the passed elem
ent |
6186 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], | 6024 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], |
6187 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], | 6025 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], |
6188 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]
, and | 6026 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]
, and |
6189 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH]. | 6027 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH]. |
6190 */ | 6028 */ |
6191 bool _safeCheckForRecursiveInterfaceInheritance(ClassElement classElt, | 6029 bool _safeCheckForRecursiveInterfaceInheritance( |
6192 List<ClassElement> path) { | 6030 ClassElement classElt, List<ClassElement> path) { |
6193 // Detect error condition. | 6031 // Detect error condition. |
6194 int size = path.length; | 6032 int size = path.length; |
6195 // If this is not the base case (size > 0), and the enclosing class is the | 6033 // If this is not the base case (size > 0), and the enclosing class is the |
6196 // passed class element then an error an error. | 6034 // passed class element then an error an error. |
6197 if (size > 0 && _enclosingClass == classElt) { | 6035 if (size > 0 && _enclosingClass == classElt) { |
6198 String enclosingClassName = _enclosingClass.displayName; | 6036 String enclosingClassName = _enclosingClass.displayName; |
6199 if (size > 1) { | 6037 if (size > 1) { |
6200 // Construct a string showing the cyclic implements path: | 6038 // Construct a string showing the cyclic implements path: |
6201 // "A, B, C, D, A" | 6039 // "A, B, C, D, A" |
6202 String separator = ", "; | 6040 String separator = ", "; |
6203 StringBuffer buffer = new StringBuffer(); | 6041 StringBuffer buffer = new StringBuffer(); |
6204 for (int i = 0; i < size; i++) { | 6042 for (int i = 0; i < size; i++) { |
6205 buffer.write(path[i].displayName); | 6043 buffer.write(path[i].displayName); |
6206 buffer.write(separator); | 6044 buffer.write(separator); |
6207 } | 6045 } |
6208 buffer.write(classElt.displayName); | 6046 buffer.write(classElt.displayName); |
6209 _errorReporter.reportErrorForOffset( | 6047 _errorReporter.reportErrorForOffset( |
6210 CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, | 6048 CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, |
6211 _enclosingClass.nameOffset, | 6049 _enclosingClass.nameOffset, enclosingClassName.length, [ |
6212 enclosingClassName.length, | 6050 enclosingClassName, |
6213 [enclosingClassName, buffer.toString()]); | 6051 buffer.toString() |
| 6052 ]); |
6214 return true; | 6053 return true; |
6215 } else { | 6054 } else { |
6216 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or | 6055 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or |
6217 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or | 6056 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or |
6218 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH | 6057 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH |
6219 _errorReporter.reportErrorForOffset( | 6058 _errorReporter.reportErrorForOffset(_getBaseCaseErrorCode(classElt), |
6220 _getBaseCaseErrorCode(classElt), | 6059 _enclosingClass.nameOffset, enclosingClassName.length, [ |
6221 _enclosingClass.nameOffset, | 6060 enclosingClassName |
6222 enclosingClassName.length, | 6061 ]); |
6223 [enclosingClassName]); | |
6224 return true; | 6062 return true; |
6225 } | 6063 } |
6226 } | 6064 } |
6227 if (path.indexOf(classElt) > 0) { | 6065 if (path.indexOf(classElt) > 0) { |
6228 return false; | 6066 return false; |
6229 } | 6067 } |
6230 path.add(classElt); | 6068 path.add(classElt); |
6231 // n-case | 6069 // n-case |
6232 InterfaceType supertype = classElt.supertype; | 6070 InterfaceType supertype = classElt.supertype; |
6233 if (supertype != null && | 6071 if (supertype != null && |
6234 _safeCheckForRecursiveInterfaceInheritance(supertype.element, path)) { | 6072 _safeCheckForRecursiveInterfaceInheritance(supertype.element, path)) { |
6235 return true; | 6073 return true; |
6236 } | 6074 } |
6237 List<InterfaceType> interfaceTypes = classElt.interfaces; | 6075 List<InterfaceType> interfaceTypes = classElt.interfaces; |
6238 for (InterfaceType interfaceType in interfaceTypes) { | 6076 for (InterfaceType interfaceType in interfaceTypes) { |
6239 if (_safeCheckForRecursiveInterfaceInheritance( | 6077 if (_safeCheckForRecursiveInterfaceInheritance( |
6240 interfaceType.element, | 6078 interfaceType.element, path)) { |
6241 path)) { | |
6242 return true; | 6079 return true; |
6243 } | 6080 } |
6244 } | 6081 } |
6245 List<InterfaceType> mixinTypes = classElt.mixins; | 6082 List<InterfaceType> mixinTypes = classElt.mixins; |
6246 for (InterfaceType mixinType in mixinTypes) { | 6083 for (InterfaceType mixinType in mixinTypes) { |
6247 if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) { | 6084 if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) { |
6248 return true; | 6085 return true; |
6249 } | 6086 } |
6250 } | 6087 } |
6251 path.removeAt(path.length - 1); | 6088 path.removeAt(path.length - 1); |
(...skipping 26 matching lines...) Expand all Loading... |
6278 if (expression is Identifier) { | 6115 if (expression is Identifier) { |
6279 Element element = expression.staticElement; | 6116 Element element = expression.staticElement; |
6280 if (element is VariableElement) { | 6117 if (element is VariableElement) { |
6281 return element; | 6118 return element; |
6282 } | 6119 } |
6283 } | 6120 } |
6284 return null; | 6121 return null; |
6285 } | 6122 } |
6286 } | 6123 } |
6287 | 6124 |
6288 class GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference extends | 6125 class GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference |
6289 GeneralizingElementVisitor<Object> { | 6126 extends GeneralizingElementVisitor<Object> { |
6290 List<Element> toCheck; | 6127 List<Element> toCheck; |
6291 | 6128 |
6292 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(this.toCheck) | 6129 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(this.toCheck) |
6293 : super(); | 6130 : super(); |
6294 | 6131 |
6295 @override | 6132 @override |
6296 Object visitClassElement(ClassElement element) { | 6133 Object visitClassElement(ClassElement element) { |
6297 // Typedefs are allowed to reference themselves via classes. | 6134 // Typedefs are allowed to reference themselves via classes. |
6298 return null; | 6135 return null; |
6299 } | 6136 } |
(...skipping 24 matching lines...) Expand all Loading... |
6324 toCheck.add(type.element); | 6161 toCheck.add(type.element); |
6325 // type arguments | 6162 // type arguments |
6326 if (type is InterfaceType) { | 6163 if (type is InterfaceType) { |
6327 InterfaceType interfaceType = type; | 6164 InterfaceType interfaceType = type; |
6328 for (DartType typeArgument in interfaceType.typeArguments) { | 6165 for (DartType typeArgument in interfaceType.typeArguments) { |
6329 _addTypeToCheck(typeArgument); | 6166 _addTypeToCheck(typeArgument); |
6330 } | 6167 } |
6331 } | 6168 } |
6332 } | 6169 } |
6333 } | 6170 } |
OLD | NEW |