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

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

Issue 1917203002: Remove more type casts (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.generated.error_verifier; 5 library analyzer.src.generated.error_verifier;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import "dart:math" as math; 8 import "dart:math" as math;
9 9
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 } 574 }
575 } 575 }
576 576
577 @override 577 @override
578 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { 578 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
579 _isInConstructorInitializer = true; 579 _isInConstructorInitializer = true;
580 try { 580 try {
581 SimpleIdentifier fieldName = node.fieldName; 581 SimpleIdentifier fieldName = node.fieldName;
582 Element staticElement = fieldName.staticElement; 582 Element staticElement = fieldName.staticElement;
583 _checkForInvalidField(node, fieldName, staticElement); 583 _checkForInvalidField(node, fieldName, staticElement);
584 _checkForFieldInitializerNotAssignable(node, staticElement); 584 if (staticElement is FieldElement) {
585 _checkForFieldInitializerNotAssignable(node, staticElement);
586 }
585 return super.visitConstructorFieldInitializer(node); 587 return super.visitConstructorFieldInitializer(node);
586 } finally { 588 } finally {
587 _isInConstructorInitializer = false; 589 _isInConstructorInitializer = false;
588 } 590 }
589 } 591 }
590 592
591 @override 593 @override
592 Object visitContinueStatement(ContinueStatement node) { 594 Object visitContinueStatement(ContinueStatement node) {
593 SimpleIdentifier labelNode = node.label; 595 SimpleIdentifier labelNode = node.label;
594 if (labelNode != null) { 596 if (labelNode != null) {
(...skipping 1210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1805 * [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT], and 1807 * [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT], and
1806 * [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]. 1808 * [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER].
1807 */ 1809 */
1808 bool _checkForAllMixinErrorCodes(WithClause withClause) { 1810 bool _checkForAllMixinErrorCodes(WithClause withClause) {
1809 if (withClause == null) { 1811 if (withClause == null) {
1810 return false; 1812 return false;
1811 } 1813 }
1812 bool problemReported = false; 1814 bool problemReported = false;
1813 for (TypeName mixinName in withClause.mixinTypes) { 1815 for (TypeName mixinName in withClause.mixinTypes) {
1814 DartType mixinType = mixinName.type; 1816 DartType mixinType = mixinName.type;
1815 if (mixinType is! InterfaceType) { 1817 if (mixinType is InterfaceType) {
1816 continue; 1818 if (_checkForExtendsOrImplementsDisallowedClass(
1817 } 1819 mixinName, CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS)) {
1818 if (_checkForExtendsOrImplementsDisallowedClass(
1819 mixinName, CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS)) {
1820 problemReported = true;
1821 } else {
1822 ClassElement mixinElement = (mixinType as InterfaceType).element;
1823 if (_checkForExtendsOrImplementsDeferredClass(
1824 mixinName, CompileTimeErrorCode.MIXIN_DEFERRED_CLASS)) {
1825 problemReported = true; 1820 problemReported = true;
1826 } 1821 } else {
1827 if (_checkForMixinDeclaresConstructor(mixinName, mixinElement)) { 1822 ClassElement mixinElement = mixinType.element;
1828 problemReported = true; 1823 if (_checkForExtendsOrImplementsDeferredClass(
1829 } 1824 mixinName, CompileTimeErrorCode.MIXIN_DEFERRED_CLASS)) {
1830 if (!enableSuperMixins && 1825 problemReported = true;
1831 _checkForMixinInheritsNotFromObject(mixinName, mixinElement)) { 1826 }
1832 problemReported = true; 1827 if (_checkForMixinDeclaresConstructor(mixinName, mixinElement)) {
1833 } 1828 problemReported = true;
1834 if (_checkForMixinReferencesSuper(mixinName, mixinElement)) { 1829 }
1835 problemReported = true; 1830 if (!enableSuperMixins &&
1831 _checkForMixinInheritsNotFromObject(mixinName, mixinElement)) {
1832 problemReported = true;
1833 }
1834 if (_checkForMixinReferencesSuper(mixinName, mixinElement)) {
1835 problemReported = true;
1836 }
1836 } 1837 }
1837 } 1838 }
1838 } 1839 }
1839 return problemReported; 1840 return problemReported;
1840 } 1841 }
1841 1842
1842 /** 1843 /**
1843 * Check for errors related to the redirected constructors. 1844 * Check for errors related to the redirected constructors.
1844 * 1845 *
1845 * See [StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE], 1846 * See [StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE],
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 * [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. 1916 * [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE].
1916 */ 1917 */
1917 void _checkForAllReturnStatementErrorCodes(ReturnStatement statement) { 1918 void _checkForAllReturnStatementErrorCodes(ReturnStatement statement) {
1918 FunctionType functionType = 1919 FunctionType functionType =
1919 _enclosingFunction == null ? null : _enclosingFunction.type; 1920 _enclosingFunction == null ? null : _enclosingFunction.type;
1920 DartType expectedReturnType = functionType == null 1921 DartType expectedReturnType = functionType == null
1921 ? DynamicTypeImpl.instance 1922 ? DynamicTypeImpl.instance
1922 : functionType.returnType; 1923 : functionType.returnType;
1923 Expression returnExpression = statement.expression; 1924 Expression returnExpression = statement.expression;
1924 // RETURN_IN_GENERATIVE_CONSTRUCTOR 1925 // RETURN_IN_GENERATIVE_CONSTRUCTOR
1925 bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && 1926 bool isGenerativeConstructor(ExecutableElement element) =>
1926 !(_enclosingFunction as ConstructorElement).isFactory; 1927 element is ConstructorElement && !element.isFactory;
1927 if (isGenerativeConstructor) { 1928 if (isGenerativeConstructor(_enclosingFunction)) {
1928 if (returnExpression == null) { 1929 if (returnExpression == null) {
1929 return; 1930 return;
1930 } 1931 }
1931 _errorReporter.reportErrorForNode( 1932 _errorReporter.reportErrorForNode(
1932 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, 1933 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR,
1933 returnExpression); 1934 returnExpression);
1934 return; 1935 return;
1935 } 1936 }
1936 // RETURN_WITHOUT_VALUE 1937 // RETURN_WITHOUT_VALUE
1937 if (returnExpression == null) { 1938 if (returnExpression == null) {
(...skipping 1333 matching lines...) Expand 10 before | Expand all | Expand 10 after
3271 _errorReporter.reportErrorForNode( 3272 _errorReporter.reportErrorForNode(
3272 errorCode, typeName, [disallowedType.displayName]); 3273 errorCode, typeName, [disallowedType.displayName]);
3273 return true; 3274 return true;
3274 } 3275 }
3275 } 3276 }
3276 return false; 3277 return false;
3277 } 3278 }
3278 3279
3279 /** 3280 /**
3280 * Verify that the given constructor field [initializer] has compatible field 3281 * Verify that the given constructor field [initializer] has compatible field
3281 * and initializer expression types. The [staticElement] is the static element 3282 * and initializer expression types. The [fieldElement] is the static element
3282 * from the name in the [ConstructorFieldInitializer]. 3283 * from the name in the [ConstructorFieldInitializer].
3283 * 3284 *
3284 * See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and 3285 * See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and
3285 * [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE]. 3286 * [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE].
3286 */ 3287 */
3287 void _checkForFieldInitializerNotAssignable( 3288 void _checkForFieldInitializerNotAssignable(
3288 ConstructorFieldInitializer initializer, Element staticElement) { 3289 ConstructorFieldInitializer initializer, FieldElement fieldElement) {
3289 // prepare field element
3290 if (staticElement is! FieldElement) {
3291 return;
3292 }
3293 FieldElement fieldElement = staticElement as FieldElement;
3294 // prepare field type 3290 // prepare field type
3295 DartType fieldType = fieldElement.type; 3291 DartType fieldType = fieldElement.type;
3296 // prepare expression type 3292 // prepare expression type
3297 Expression expression = initializer.expression; 3293 Expression expression = initializer.expression;
3298 if (expression == null) { 3294 if (expression == null) {
3299 return; 3295 return;
3300 } 3296 }
3301 // test the static type of the expression 3297 // test the static type of the expression
3302 DartType staticType = getStaticType(expression); 3298 DartType staticType = getStaticType(expression);
3303 if (staticType == null) { 3299 if (staticType == null) {
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
3733 // OK, in comment 3729 // OK, in comment
3734 if (_isInComment) { 3730 if (_isInComment) {
3735 return; 3731 return;
3736 } 3732 }
3737 // OK, target is a type 3733 // OK, target is a type
3738 if (typeReference != null) { 3734 if (typeReference != null) {
3739 return; 3735 return;
3740 } 3736 }
3741 // prepare member Element 3737 // prepare member Element
3742 Element element = name.staticElement; 3738 Element element = name.staticElement;
3743 if (element is! ExecutableElement) { 3739 if (element is ExecutableElement) {
3744 return; 3740 // OK, top-level element
3741 if (element.enclosingElement is! ClassElement) {
3742 return;
3743 }
3744 // OK, instance member
3745 if (!element.isStatic) {
3746 return;
3747 }
3748 _errorReporter.reportErrorForNode(
3749 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
3750 name,
3751 [name.name]);
3745 } 3752 }
3746 ExecutableElement executableElement = element as ExecutableElement;
3747 // OK, top-level element
3748 if (executableElement.enclosingElement is! ClassElement) {
3749 return;
3750 }
3751 // OK, instance member
3752 if (!executableElement.isStatic) {
3753 return;
3754 }
3755
3756 _errorReporter.reportErrorForNode(
3757 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
3758 name,
3759 [name.name]);
3760 } 3753 }
3761 3754
3762 /** 3755 /**
3763 * Check whether the given [executableElement] collides with the name of a 3756 * Check whether the given [executableElement] collides with the name of a
3764 * static method in one of its superclasses, and reports the appropriate 3757 * static method in one of its superclasses, and reports the appropriate
3765 * warning if it does. The [errorNameTarget] is the node to report problems 3758 * warning if it does. The [errorNameTarget] is the node to report problems
3766 * on. 3759 * on.
3767 * 3760 *
3768 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST ATIC]. 3761 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST ATIC].
3769 */ 3762 */
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
4086 * Check to make sure that all similarly typed accessors are of the same type 4079 * Check to make sure that all similarly typed accessors are of the same type
4087 * (including inherited accessors). 4080 * (including inherited accessors).
4088 * 4081 *
4089 * See [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES], and 4082 * See [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES], and
4090 * [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE]. 4083 * [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE].
4091 */ 4084 */
4092 void _checkForMismatchedAccessorTypes( 4085 void _checkForMismatchedAccessorTypes(
4093 Declaration accessorDeclaration, String accessorTextName) { 4086 Declaration accessorDeclaration, String accessorTextName) {
4094 ExecutableElement accessorElement = 4087 ExecutableElement accessorElement =
4095 accessorDeclaration.element as ExecutableElement; 4088 accessorDeclaration.element as ExecutableElement;
4096 if (accessorElement is! PropertyAccessorElement) { 4089 if (accessorElement is PropertyAccessorElement) {
4097 return; 4090 PropertyAccessorElement counterpartAccessor = null;
4098 } 4091 ClassElement enclosingClassForCounterpart = null;
4099 PropertyAccessorElement propertyAccessorElement = 4092 if (accessorElement.isGetter) {
4100 accessorElement as PropertyAccessorElement; 4093 counterpartAccessor = accessorElement.correspondingSetter;
4101 PropertyAccessorElement counterpartAccessor = null; 4094 } else {
4102 ClassElement enclosingClassForCounterpart = null; 4095 counterpartAccessor = accessorElement.correspondingGetter;
4103 if (propertyAccessorElement.isGetter) { 4096 // If the setter and getter are in the same enclosing element, return,
4104 counterpartAccessor = propertyAccessorElement.correspondingSetter; 4097 // this prevents having MISMATCHED_GETTER_AND_SETTER_TYPES reported twic e.
4105 } else { 4098 if (counterpartAccessor != null &&
4106 counterpartAccessor = propertyAccessorElement.correspondingGetter; 4099 identical(counterpartAccessor.enclosingElement,
4107 // If the setter and getter are in the same enclosing element, return, 4100 accessorElement.enclosingElement)) {
4108 // this prevents having MISMATCHED_GETTER_AND_SETTER_TYPES reported twice. 4101 return;
4109 if (counterpartAccessor != null &&
4110 identical(counterpartAccessor.enclosingElement,
4111 propertyAccessorElement.enclosingElement)) {
4112 return;
4113 }
4114 }
4115 if (counterpartAccessor == null) {
4116 // If the accessor is declared in a class, check the superclasses.
4117 if (_enclosingClass != null) {
4118 // Figure out the correct identifier to lookup in the inheritance graph,
4119 // if 'x', then 'x=', or if 'x=', then 'x'.
4120 String lookupIdentifier = propertyAccessorElement.name;
4121 if (StringUtilities.endsWithChar(lookupIdentifier, 0x3D)) {
4122 lookupIdentifier =
4123 lookupIdentifier.substring(0, lookupIdentifier.length - 1);
4124 } else {
4125 lookupIdentifier += "=";
4126 }
4127 // lookup with the identifier.
4128 ExecutableElement elementFromInheritance = _inheritanceManager
4129 .lookupInheritance(_enclosingClass, lookupIdentifier);
4130 // Verify that we found something, and that it is an accessor
4131 if (elementFromInheritance != null &&
4132 elementFromInheritance is PropertyAccessorElement) {
4133 enclosingClassForCounterpart =
4134 elementFromInheritance.enclosingElement as ClassElement;
4135 counterpartAccessor = elementFromInheritance;
4136 } 4102 }
4137 } 4103 }
4138 if (counterpartAccessor == null) { 4104 if (counterpartAccessor == null) {
4139 return; 4105 // If the accessor is declared in a class, check the superclasses.
4106 if (_enclosingClass != null) {
4107 // Figure out the correct identifier to lookup in the inheritance grap h,
4108 // if 'x', then 'x=', or if 'x=', then 'x'.
4109 String lookupIdentifier = accessorElement.name;
4110 if (StringUtilities.endsWithChar(lookupIdentifier, 0x3D)) {
4111 lookupIdentifier =
4112 lookupIdentifier.substring(0, lookupIdentifier.length - 1);
4113 } else {
4114 lookupIdentifier += "=";
4115 }
4116 // lookup with the identifier.
4117 ExecutableElement elementFromInheritance = _inheritanceManager
4118 .lookupInheritance(_enclosingClass, lookupIdentifier);
4119 // Verify that we found something, and that it is an accessor
4120 if (elementFromInheritance != null &&
4121 elementFromInheritance is PropertyAccessorElement) {
4122 enclosingClassForCounterpart =
4123 elementFromInheritance.enclosingElement as ClassElement;
4124 counterpartAccessor = elementFromInheritance;
4125 }
4126 }
4127 if (counterpartAccessor == null) {
4128 return;
4129 }
4140 } 4130 }
4141 } 4131 // Default of null == no accessor or no type (dynamic)
4142 // Default of null == no accessor or no type (dynamic) 4132 DartType getterType = null;
4143 DartType getterType = null; 4133 DartType setterType = null;
4144 DartType setterType = null; 4134 // Get an existing counterpart accessor if any.
4145 // Get an existing counterpart accessor if any. 4135 if (accessorElement.isGetter) {
4146 if (propertyAccessorElement.isGetter) { 4136 getterType = _getGetterType(accessorElement);
4147 getterType = _getGetterType(propertyAccessorElement); 4137 setterType = _getSetterType(counterpartAccessor);
4148 setterType = _getSetterType(counterpartAccessor); 4138 } else if (accessorElement.isSetter) {
4149 } else if (propertyAccessorElement.isSetter) { 4139 setterType = _getSetterType(accessorElement);
4150 setterType = _getSetterType(propertyAccessorElement); 4140 getterType = _getGetterType(counterpartAccessor);
4151 getterType = _getGetterType(counterpartAccessor); 4141 }
4152 } 4142 // If either types are not assignable to each other, report an error
4153 // If either types are not assignable to each other, report an error 4143 // (if the getter is null, it is dynamic which is assignable to everything ).
4154 // (if the getter is null, it is dynamic which is assignable to everything). 4144 if (setterType != null &&
4155 if (setterType != null && 4145 getterType != null &&
4156 getterType != null && 4146 !_typeSystem.isAssignableTo(getterType, setterType)) {
4157 !_typeSystem.isAssignableTo(getterType, setterType)) { 4147 if (enclosingClassForCounterpart == null) {
4158 if (enclosingClassForCounterpart == null) { 4148 _errorReporter.reportTypeErrorForNode(
4159 _errorReporter.reportTypeErrorForNode( 4149 StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
4160 StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, 4150 accessorDeclaration,
4161 accessorDeclaration, 4151 [accessorTextName, setterType, getterType]);
4162 [accessorTextName, setterType, getterType]); 4152 } else {
4163 } else { 4153 _errorReporter.reportTypeErrorForNode(
4164 _errorReporter.reportTypeErrorForNode( 4154 StaticWarningCode
4165 StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, 4155 .MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,
4166 accessorDeclaration, [ 4156 accessorDeclaration,
4167 accessorTextName, 4157 [
4168 setterType, 4158 accessorTextName,
4169 getterType, 4159 setterType,
4170 enclosingClassForCounterpart.displayName 4160 getterType,
4171 ]); 4161 enclosingClassForCounterpart.displayName
4162 ]);
4163 }
4172 } 4164 }
4173 } 4165 }
4174 } 4166 }
4175 4167
4176 /** 4168 /**
4177 * Check to make sure that the given switch [statement] whose static type is 4169 * Check to make sure that the given switch [statement] whose static type is
4178 * an enum type either have a default case or include all of the enum 4170 * an enum type either have a default case or include all of the enum
4179 * constants. 4171 * constants.
4180 */ 4172 */
4181 void _checkForMissingEnumConstantInSwitch(SwitchStatement statement) { 4173 void _checkForMissingEnumConstantInSwitch(SwitchStatement statement) {
4182 // TODO(brianwilkerson) This needs to be checked after constant values have 4174 // TODO(brianwilkerson) This needs to be checked after constant values have
4183 // been computed. 4175 // been computed.
4184 Expression expression = statement.expression; 4176 Expression expression = statement.expression;
4185 DartType expressionType = getStaticType(expression); 4177 DartType expressionType = getStaticType(expression);
4186 if (expressionType == null) { 4178 if (expressionType == null) {
4187 return; 4179 return;
4188 } 4180 }
4189 Element expressionElement = expressionType.element; 4181 Element expressionElement = expressionType.element;
4190 if (expressionElement is! ClassElement) { 4182 if (expressionElement is ClassElement) {
4191 return; 4183 if (!expressionElement.isEnum) {
4192 }
4193 ClassElement classElement = expressionElement as ClassElement;
4194 if (!classElement.isEnum) {
4195 return;
4196 }
4197 List<String> constantNames = <String>[];
4198 List<FieldElement> fields = classElement.fields;
4199 int fieldCount = fields.length;
4200 for (int i = 0; i < fieldCount; i++) {
4201 FieldElement field = fields[i];
4202 if (field.isStatic && !field.isSynthetic) {
4203 constantNames.add(field.name);
4204 }
4205 }
4206 NodeList<SwitchMember> members = statement.members;
4207 int memberCount = members.length;
4208 for (int i = 0; i < memberCount; i++) {
4209 SwitchMember member = members[i];
4210 if (member is SwitchDefault) {
4211 return; 4184 return;
4212 } 4185 }
4213 String constantName = _getConstantName((member as SwitchCase).expression); 4186 List<String> constantNames = <String>[];
4214 if (constantName != null) { 4187 List<FieldElement> fields = expressionElement.fields;
4215 constantNames.remove(constantName); 4188 int fieldCount = fields.length;
4189 for (int i = 0; i < fieldCount; i++) {
4190 FieldElement field = fields[i];
4191 if (field.isStatic && !field.isSynthetic) {
4192 constantNames.add(field.name);
4193 }
4216 } 4194 }
4217 } 4195 NodeList<SwitchMember> members = statement.members;
4218 if (constantNames.isEmpty) { 4196 int memberCount = members.length;
4219 return; 4197 for (int i = 0; i < memberCount; i++) {
4220 } 4198 SwitchMember member = members[i];
4221 for (int i = 0; i < constantNames.length; i++) { 4199 if (member is SwitchDefault) {
4222 int offset = statement.offset; 4200 return;
4223 int end = statement.rightParenthesis.end; 4201 }
4224 _errorReporter.reportErrorForOffset( 4202 String constantName =
4225 StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH, 4203 _getConstantName((member as SwitchCase).expression);
4226 offset, 4204 if (constantName != null) {
4227 end - offset, 4205 constantNames.remove(constantName);
4228 [constantNames[i]]); 4206 }
4207 }
4208 if (constantNames.isEmpty) {
4209 return;
4210 }
4211 for (int i = 0; i < constantNames.length; i++) {
4212 int offset = statement.offset;
4213 int end = statement.rightParenthesis.end;
4214 _errorReporter.reportErrorForOffset(
4215 StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
4216 offset,
4217 end - offset,
4218 [constantNames[i]]);
4219 }
4229 } 4220 }
4230 } 4221 }
4231 4222
4232 void _checkForMissingJSLibAnnotation(Annotation node) { 4223 void _checkForMissingJSLibAnnotation(Annotation node) {
4233 if (node.elementAnnotation?.isJS ?? false) { 4224 if (node.elementAnnotation?.isJS ?? false) {
4234 Element element = ElementLocator.locate(node.parent); 4225 Element element = ElementLocator.locate(node.parent);
4235 if (element?.library?.isJS != true) { 4226 if (element?.library?.isJS != true) {
4236 _errorReporter.reportErrorForNode( 4227 _errorReporter.reportErrorForNode(
4237 HintCode.MISSING_JS_LIB_ANNOTATION, node, [element.name]); 4228 HintCode.MISSING_JS_LIB_ANNOTATION, node, [element.name]);
4238 } 4229 }
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after
5121 // OK, in comment 5112 // OK, in comment
5122 if (_isInComment) { 5113 if (_isInComment) {
5123 return; 5114 return;
5124 } 5115 }
5125 // OK, target is not a type 5116 // OK, target is not a type
5126 if (typeReference == null) { 5117 if (typeReference == null) {
5127 return; 5118 return;
5128 } 5119 }
5129 // prepare member Element 5120 // prepare member Element
5130 Element element = name.staticElement; 5121 Element element = name.staticElement;
5131 if (element is! ExecutableElement) { 5122 if (element is ExecutableElement) {
5132 return; 5123 // OK, static
5124 if (element.isStatic) {
5125 return;
5126 }
5127 _errorReporter.reportErrorForNode(
5128 StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
5129 name,
5130 [name.name]);
5133 } 5131 }
5134 ExecutableElement memberElement = element as ExecutableElement;
5135 // OK, static
5136 if (memberElement.isStatic) {
5137 return;
5138 }
5139
5140 _errorReporter.reportErrorForNode(
5141 StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]);
5142 } 5132 }
5143 5133
5144 /** 5134 /**
5145 * Check that the type of the expression in the given 'switch' [statement] is 5135 * Check that the type of the expression in the given 'switch' [statement] is
5146 * assignable to the type of the 'case' members. 5136 * assignable to the type of the 'case' members.
5147 * 5137 *
5148 * See [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE]. 5138 * See [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE].
5149 */ 5139 */
5150 void _checkForSwitchExpressionNotAssignable(SwitchStatement statement) { 5140 void _checkForSwitchExpressionNotAssignable(SwitchStatement statement) {
5151 // prepare 'switch' expression type 5141 // prepare 'switch' expression type
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
5210 if (typeName.typeArguments == null) { 5200 if (typeName.typeArguments == null) {
5211 return; 5201 return;
5212 } 5202 }
5213 // prepare Type 5203 // prepare Type
5214 DartType type = typeName.type; 5204 DartType type = typeName.type;
5215 if (type == null) { 5205 if (type == null) {
5216 return; 5206 return;
5217 } 5207 }
5218 // prepare ClassElement 5208 // prepare ClassElement
5219 Element element = type.element; 5209 Element element = type.element;
5220 if (element is! ClassElement) { 5210 if (element is ClassElement) {
5221 return; 5211 // prepare type parameters
5222 } 5212 List<DartType> typeParameters = element.type.typeArguments;
5223 ClassElement classElement = element as ClassElement; 5213 List<TypeParameterElement> boundingElts = element.typeParameters;
5224 // prepare type parameters 5214 // iterate over each bounded type parameter and corresponding argument
5225 List<DartType> typeParameters = classElement.type.typeArguments; 5215 NodeList<TypeName> typeNameArgList = typeName.typeArguments.arguments;
5226 List<TypeParameterElement> boundingElts = classElement.typeParameters; 5216 List<DartType> typeArguments = (type as InterfaceType).typeArguments;
5227 // iterate over each bounded type parameter and corresponding argument 5217 int loopThroughIndex =
5228 NodeList<TypeName> typeNameArgList = typeName.typeArguments.arguments; 5218 math.min(typeNameArgList.length, boundingElts.length);
5229 List<DartType> typeArguments = (type as InterfaceType).typeArguments;
5230 int loopThroughIndex =
5231 math.min(typeNameArgList.length, boundingElts.length);
5232 5219
5233 for (int i = 0; i < loopThroughIndex; i++) { 5220 for (int i = 0; i < loopThroughIndex; i++) {
5234 TypeName argTypeName = typeNameArgList[i]; 5221 TypeName argTypeName = typeNameArgList[i];
5235 DartType argType = argTypeName.type; 5222 DartType argType = argTypeName.type;
5236 DartType boundType = boundingElts[i].bound; 5223 DartType boundType = boundingElts[i].bound;
5237 if (argType != null && boundType != null) { 5224 if (argType != null && boundType != null) {
5238 if (typeArguments.length != 0 && 5225 if (typeArguments.length != 0 &&
5239 typeArguments.length == typeParameters.length) { 5226 typeArguments.length == typeParameters.length) {
5240 boundType = boundType.substitute2(typeArguments, typeParameters); 5227 boundType = boundType.substitute2(typeArguments, typeParameters);
5241 }
5242 if (!_typeSystem.isSubtypeOf(argType, boundType)) {
5243 ErrorCode errorCode;
5244 if (_isInConstInstanceCreation) {
5245 errorCode = CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
5246 } else {
5247 errorCode = StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
5248 } 5228 }
5249 _errorReporter.reportTypeErrorForNode( 5229 if (!_typeSystem.isSubtypeOf(argType, boundType)) {
5250 errorCode, argTypeName, [argType, boundType]); 5230 ErrorCode errorCode;
5231 if (_isInConstInstanceCreation) {
5232 errorCode =
5233 CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
5234 } else {
5235 errorCode =
5236 StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
5237 }
5238 _errorReporter.reportTypeErrorForNode(
5239 errorCode, argTypeName, [argType, boundType]);
5240 }
5251 } 5241 }
5252 } 5242 }
5253 } 5243 }
5254 } 5244 }
5255 5245
5256 /** 5246 /**
5257 * Check whether the given type [name] is a type parameter being used to 5247 * Check whether the given type [name] is a type parameter being used to
5258 * define a static member. 5248 * define a static member.
5259 * 5249 *
5260 * See [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]. 5250 * See [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC].
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after
5898 * have to equal or be a subtype of the given executable element, this is due 5888 * have to equal or be a subtype of the given executable element, this is due
5899 * to the specific use where this method is used in 5889 * to the specific use where this method is used in
5900 * [_checkForNonAbstractClassInheritsAbstractMember]. 5890 * [_checkForNonAbstractClassInheritsAbstractMember].
5901 */ 5891 */
5902 bool _isMemberInClassOrMixin( 5892 bool _isMemberInClassOrMixin(
5903 ExecutableElement executableElement, ClassElement classElement) { 5893 ExecutableElement executableElement, ClassElement classElement) {
5904 ExecutableElement foundElt = null; 5894 ExecutableElement foundElt = null;
5905 String executableName = executableElement.name; 5895 String executableName = executableElement.name;
5906 if (executableElement is MethodElement) { 5896 if (executableElement is MethodElement) {
5907 foundElt = classElement.getMethod(executableName); 5897 foundElt = classElement.getMethod(executableName);
5908 if (foundElt != null && !(foundElt as MethodElement).isAbstract) { 5898 if (foundElt != null && !foundElt.isAbstract) {
5909 return true; 5899 return true;
5910 } 5900 }
5911 List<InterfaceType> mixins = classElement.mixins; 5901 List<InterfaceType> mixins = classElement.mixins;
5912 for (int i = 0; i < mixins.length && foundElt == null; i++) { 5902 for (int i = 0; i < mixins.length && foundElt == null; i++) {
5913 foundElt = mixins[i].getMethod(executableName); 5903 foundElt = mixins[i].getMethod(executableName);
5914 } 5904 }
5915 if (foundElt != null && !(foundElt as MethodElement).isAbstract) { 5905 if (foundElt != null && !foundElt.isAbstract) {
5916 return true; 5906 return true;
5917 } 5907 }
5918 } else if (executableElement is PropertyAccessorElement) { 5908 } else if (executableElement is PropertyAccessorElement) {
5919 if (executableElement.isGetter) { 5909 if (executableElement.isGetter) {
5920 foundElt = classElement.getGetter(executableName); 5910 foundElt = classElement.getGetter(executableName);
5921 } 5911 }
5922 if (foundElt == null && executableElement.isSetter) { 5912 if (foundElt == null && executableElement.isSetter) {
5923 foundElt = classElement.getSetter(executableName); 5913 foundElt = classElement.getSetter(executableName);
5924 } 5914 }
5925 if (foundElt != null && 5915 if (foundElt != null &&
5926 !(foundElt as PropertyAccessorElement).isAbstract) { 5916 !(foundElt as PropertyAccessorElement).isAbstract) {
5927 return true; 5917 return true;
5928 } 5918 }
5929 List<InterfaceType> mixins = classElement.mixins; 5919 List<InterfaceType> mixins = classElement.mixins;
5930 for (int i = 0; i < mixins.length && foundElt == null; i++) { 5920 for (int i = 0; i < mixins.length && foundElt == null; i++) {
5931 foundElt = mixins[i].getGetter(executableName); 5921 foundElt = mixins[i].getGetter(executableName);
5932 if (foundElt == null) { 5922 if (foundElt == null) {
5933 foundElt = mixins[i].getSetter(executableName); 5923 foundElt = mixins[i].getSetter(executableName);
5934 } 5924 }
5935 } 5925 }
5936 if (foundElt != null && 5926 if (foundElt != null && !foundElt.isAbstract) {
5937 !(foundElt as PropertyAccessorElement).isAbstract) {
5938 return true; 5927 return true;
5939 } 5928 }
5940 } 5929 }
5941 return false; 5930 return false;
5942 } 5931 }
5943 5932
5944 /** 5933 /**
5945 * Return `true` if the given 'this' [expression] is in a valid context. 5934 * Return `true` if the given 'this' [expression] is in a valid context.
5946 */ 5935 */
5947 bool _isThisInValidContext(ThisExpression expression) { 5936 bool _isThisInValidContext(ThisExpression expression) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
6149 class _InvocationCollector extends RecursiveAstVisitor { 6138 class _InvocationCollector extends RecursiveAstVisitor {
6150 final List<String> superCalls = <String>[]; 6139 final List<String> superCalls = <String>[];
6151 6140
6152 @override 6141 @override
6153 visitMethodInvocation(MethodInvocation node) { 6142 visitMethodInvocation(MethodInvocation node) {
6154 if (node.target is SuperExpression) { 6143 if (node.target is SuperExpression) {
6155 superCalls.add(node.methodName.name); 6144 superCalls.add(node.methodName.name);
6156 } 6145 }
6157 } 6146 }
6158 } 6147 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698