| 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 |