| 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'; |
| 11 | 11 |
| 12 import 'ast.dart'; | 12 import 'ast.dart'; |
| 13 import 'constant.dart'; | 13 import 'constant.dart'; |
| 14 import 'element.dart'; | 14 import 'element.dart'; |
| 15 import 'element_resolver.dart'; | 15 import 'element_resolver.dart'; |
| 16 import 'error.dart'; | 16 import 'error.dart'; |
| 17 import 'java_engine.dart'; | 17 import 'java_engine.dart'; |
| 18 import 'parser.dart' show Parser, ParserErrorCode; | 18 import 'parser.dart' show Parser, ParserErrorCode; |
| 19 import 'resolver.dart'; | 19 import 'resolver.dart'; |
| 20 import 'scanner.dart' as sc; | 20 import 'scanner.dart' as sc; |
| 21 import 'sdk.dart' show DartSdk, SdkLibrary; | 21 import 'sdk.dart' show DartSdk, SdkLibrary; |
| 22 import 'utilities_dart.dart'; | 22 import 'utilities_dart.dart'; |
| 23 | 23 |
| 24 /** | 24 /** |
| 25 * Instances of the class `ErrorVerifier` traverse an AST structure looking for
additional | 25 * A visitor used to traverse an AST structure looking for additional errors and |
| 26 * errors and warnings not covered by the parser and resolver. | 26 * warnings not covered by the parser and resolver. |
| 27 */ | 27 */ |
| 28 class ErrorVerifier extends RecursiveAstVisitor<Object> { | 28 class ErrorVerifier extends RecursiveAstVisitor<Object> { |
| 29 /** | 29 /** |
| 30 * Static final string with value `"getter "` used in the construction of the | 30 * Static final string with value `"getter "` used in the construction of the |
| 31 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and si
milar, error | 31 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and |
| 32 * code messages. | 32 * similar, error code messages. |
| 33 * | 33 * |
| 34 * See [_checkForNonAbstractClassInheritsAbstractMember]. | 34 * See [_checkForNonAbstractClassInheritsAbstractMember]. |
| 35 */ | 35 */ |
| 36 static String _GETTER_SPACE = "getter "; | 36 static String _GETTER_SPACE = "getter "; |
| 37 | 37 |
| 38 /** | 38 /** |
| 39 * Static final string with value `"setter "` used in the construction of the | 39 * Static final string with value `"setter "` used in the construction of the |
| 40 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and si
milar, error | 40 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and |
| 41 * code messages. | 41 * similar, error code messages. |
| 42 * | 42 * |
| 43 * See [_checkForNonAbstractClassInheritsAbstractMember]. | 43 * See [_checkForNonAbstractClassInheritsAbstractMember]. |
| 44 */ | 44 */ |
| 45 static String _SETTER_SPACE = "setter "; | 45 static String _SETTER_SPACE = "setter "; |
| 46 | 46 |
| 47 /** | 47 /** |
| 48 * The error reporter by which errors will be reported. | 48 * The error reporter by which errors will be reported. |
| 49 */ | 49 */ |
| 50 final ErrorReporter _errorReporter; | 50 final ErrorReporter _errorReporter; |
| 51 | 51 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 68 * The object providing access to the types defined by the language. | 68 * The object providing access to the types defined by the language. |
| 69 */ | 69 */ |
| 70 final TypeProvider _typeProvider; | 70 final TypeProvider _typeProvider; |
| 71 | 71 |
| 72 /** | 72 /** |
| 73 * The manager for the inheritance mappings. | 73 * The manager for the inheritance mappings. |
| 74 */ | 74 */ |
| 75 final InheritanceManager _inheritanceManager; | 75 final InheritanceManager _inheritanceManager; |
| 76 | 76 |
| 77 /** | 77 /** |
| 78 * This is set to `true` iff the visitor is currently visiting children nodes
of a | 78 * A flag indicating whether the visitor is currently within a constructor |
| 79 * [ConstructorDeclaration] and the constructor is 'const'. | 79 * declaration that is 'const'. |
| 80 * | 80 * |
| 81 * See [visitConstructorDeclaration]. | 81 * See [visitConstructorDeclaration]. |
| 82 */ | 82 */ |
| 83 bool _isEnclosingConstructorConst = false; | 83 bool _isEnclosingConstructorConst = false; |
| 84 | 84 |
| 85 /** | 85 /** |
| 86 * A flag indicating whether we are currently within a function body marked as
being asynchronous. | 86 * A flag indicating whether we are currently within a function body marked as |
| 87 * being asynchronous. |
| 87 */ | 88 */ |
| 88 bool _inAsync = false; | 89 bool _inAsync = false; |
| 89 | 90 |
| 90 /** | 91 /** |
| 91 * A flag indicating whether we are currently within a function body marked as
being a generator. | 92 * A flag indicating whether we are currently within a function body marked a |
| 93 * being a generator. |
| 92 */ | 94 */ |
| 93 bool _inGenerator = false; | 95 bool _inGenerator = false; |
| 94 | 96 |
| 95 /** | 97 /** |
| 96 * This is set to `true` iff the visitor is currently visiting children nodes
of a | 98 * A flag indicating whether the visitor is currently within a catch clause. |
| 97 * [CatchClause]. | |
| 98 * | 99 * |
| 99 * See [visitCatchClause]. | 100 * See [visitCatchClause]. |
| 100 */ | 101 */ |
| 101 bool _isInCatchClause = false; | 102 bool _isInCatchClause = false; |
| 102 | 103 |
| 103 /** | 104 /** |
| 104 * This is set to `true` iff the visitor is currently visiting children nodes
of an | 105 * A flag indicating whether the visitor is currently within a comment. |
| 105 * [Comment]. | |
| 106 */ | 106 */ |
| 107 bool _isInComment = false; | 107 bool _isInComment = false; |
| 108 | 108 |
| 109 /** | 109 /** |
| 110 * This is set to `true` iff the visitor is currently visiting children nodes
of an | 110 * A flag indicating whether the visitor is currently within an instance |
| 111 * [InstanceCreationExpression]. | 111 * creation expression. |
| 112 */ | 112 */ |
| 113 bool _isInConstInstanceCreation = false; | 113 bool _isInConstInstanceCreation = false; |
| 114 | 114 |
| 115 /** | 115 /** |
| 116 * This is set to `true` iff the visitor is currently visiting children nodes
of a native | 116 * A flag indicating whether the visitor is currently within a native class |
| 117 * [ClassDeclaration]. | 117 * declaration. |
| 118 */ | 118 */ |
| 119 bool _isInNativeClass = false; | 119 bool _isInNativeClass = false; |
| 120 | 120 |
| 121 /** | 121 /** |
| 122 * This is set to `true` iff the visitor is currently visiting a static variab
le | 122 * A flag indicating whether the visitor is currently within a static variable |
| 123 * declaration. | 123 * declaration. |
| 124 */ | 124 */ |
| 125 bool _isInStaticVariableDeclaration = false; | 125 bool _isInStaticVariableDeclaration = false; |
| 126 | 126 |
| 127 /** | 127 /** |
| 128 * This is set to `true` iff the visitor is currently visiting an instance var
iable | 128 * A flag indicating whether the visitor is currently within an instance |
| 129 * declaration. | 129 * variable declaration. |
| 130 */ | 130 */ |
| 131 bool _isInInstanceVariableDeclaration = false; | 131 bool _isInInstanceVariableDeclaration = false; |
| 132 | 132 |
| 133 /** | 133 /** |
| 134 * This is set to `true` iff the visitor is currently visiting an instance var
iable | 134 * A flag indicating whether the visitor is currently within an instance |
| 135 * initializer. | 135 * variable initializer. |
| 136 */ | 136 */ |
| 137 bool _isInInstanceVariableInitializer = false; | 137 bool _isInInstanceVariableInitializer = false; |
| 138 | 138 |
| 139 /** | 139 /** |
| 140 * This is set to `true` iff the visitor is currently visiting a | 140 * A flag indicating whether the visitor is currently within a constructor |
| 141 * [ConstructorInitializer]. | 141 * initializer. |
| 142 */ | 142 */ |
| 143 bool _isInConstructorInitializer = false; | 143 bool _isInConstructorInitializer = false; |
| 144 | 144 |
| 145 /** | 145 /** |
| 146 * This is set to `true` iff the visitor is currently visiting a | 146 * This is set to `true` iff the visitor is currently within a function typed |
| 147 * [FunctionTypedFormalParameter]. | 147 * formal parameter. |
| 148 */ | 148 */ |
| 149 bool _isInFunctionTypedFormalParameter = false; | 149 bool _isInFunctionTypedFormalParameter = false; |
| 150 | 150 |
| 151 /** | 151 /** |
| 152 * This is set to `true` iff the visitor is currently visiting a static method
. By "method" | 152 * A flag indicating whether the visitor is currently within a static method. |
| 153 * here getter, setter and operator declarations are also implied since they a
re all represented | 153 * By "method" here getter, setter and operator declarations are also implied |
| 154 * with a [MethodDeclaration] in the AST structure. | 154 * since they are all represented with a [MethodDeclaration] in the AST |
| 155 * structure. |
| 155 */ | 156 */ |
| 156 bool _isInStaticMethod = false; | 157 bool _isInStaticMethod = false; |
| 157 | 158 |
| 158 /** | 159 /** |
| 159 * This is set to `true` iff the visitor is currently visiting a factory const
ructor. | 160 * A flag indicating whether the visitor is currently within a factory |
| 161 * constructor. |
| 160 */ | 162 */ |
| 161 bool _isInFactory = false; | 163 bool _isInFactory = false; |
| 162 | 164 |
| 163 /** | 165 /** |
| 164 * This is set to `true` iff the visitor is currently visiting code in the SDK
. | 166 * A flag indicating whether the visitor is currently within code in the SDK. |
| 165 */ | 167 */ |
| 166 bool _isInSystemLibrary = false; | 168 bool _isInSystemLibrary = false; |
| 167 | 169 |
| 168 /** | 170 /** |
| 169 * A flag indicating whether the current library contains at least one import
directive with a URI | 171 * A flag indicating whether the current library contains at least one import |
| 170 * that uses the "dart-ext" scheme. | 172 * directive with a URI that uses the "dart-ext" scheme. |
| 171 */ | 173 */ |
| 172 bool _hasExtUri = false; | 174 bool _hasExtUri = false; |
| 173 | 175 |
| 174 /** | 176 /** |
| 175 * This is set to `false` on the entry of every [BlockFunctionBody], and is re
stored | 177 * This is set to `false` on the entry of every [BlockFunctionBody], and is |
| 176 * to the enclosing value on exit. The value is used in | 178 * restored to the enclosing value on exit. The value is used in |
| 177 * [checkForMixedReturns] to prevent both | 179 * [_checkForMixedReturns] to prevent both |
| 178 * [StaticWarningCode.MIXED_RETURN_TYPES] and [StaticWarningCode.RETURN_WITHOU
T_VALUE] | 180 * [StaticWarningCode.MIXED_RETURN_TYPES] and |
| 179 * from being generated in the same function body. | 181 * [StaticWarningCode.RETURN_WITHOUT_VALUE] from being generated in the same |
| 182 * function body. |
| 180 */ | 183 */ |
| 181 bool _hasReturnWithoutValue = false; | 184 bool _hasReturnWithoutValue = false; |
| 182 | 185 |
| 183 /** | 186 /** |
| 184 * The class containing the AST nodes being visited, or `null` if we are not i
n the scope of | 187 * The class containing the AST nodes being visited, or `null` if we are not |
| 185 * a class. | 188 * in the scope of a class. |
| 186 */ | 189 */ |
| 187 ClassElement _enclosingClass; | 190 ClassElement _enclosingClass; |
| 188 | 191 |
| 189 /** | 192 /** |
| 190 * The method or function that we are currently visiting, or `null` if we are
not inside a | 193 * The method or function that we are currently visiting, or `null` if we are |
| 191 * method or function. | 194 * not inside a method or function. |
| 192 */ | 195 */ |
| 193 ExecutableElement _enclosingFunction; | 196 ExecutableElement _enclosingFunction; |
| 194 | 197 |
| 195 /** | 198 /** |
| 196 * The return statements found in the method or function that we are currently
visiting that have | 199 * The return statements found in the method or function that we are currently |
| 197 * a return value. | 200 * visiting that have a return value. |
| 198 */ | 201 */ |
| 199 List<ReturnStatement> _returnsWith = new List<ReturnStatement>(); | 202 List<ReturnStatement> _returnsWith = new List<ReturnStatement>(); |
| 200 | 203 |
| 201 /** | 204 /** |
| 202 * The return statements found in the method or function that we are currently
visiting that do | 205 * The return statements found in the method or function that we are currently |
| 203 * not have a return value. | 206 * visiting that do not have a return value. |
| 204 */ | 207 */ |
| 205 List<ReturnStatement> _returnsWithout = new List<ReturnStatement>(); | 208 List<ReturnStatement> _returnsWithout = new List<ReturnStatement>(); |
| 206 | 209 |
| 207 /** | 210 /** |
| 208 * This map is initialized when visiting the contents of a class declaration.
If the visitor is | 211 * This map is initialized when visiting the contents of a class declaration. |
| 209 * not in an enclosing class declaration, then the map is set to `null`. | 212 * If the visitor is not in an enclosing class declaration, then the map is |
| 213 * set to `null`. |
| 210 * | 214 * |
| 211 * When set the map maps the set of [FieldElement]s in the class to an | 215 * When set the map maps the set of [FieldElement]s in the class to an |
| 212 * [INIT_STATE.NOT_INIT] or [INIT_STATE.INIT_IN_DECLARATION]. <code>checkFor*<
/code> | 216 * [INIT_STATE.NOT_INIT] or [INIT_STATE.INIT_IN_DECLARATION]. The `checkFor*` |
| 213 * methods, specifically [checkForAllFinalInitializedErrorCodes], | 217 * methods, specifically [_checkForAllFinalInitializedErrorCodes], can make a |
| 214 * can make a copy of the map to compute error code states. <code>checkFor*</c
ode> methods should | 218 * copy of the map to compute error code states. The `checkFor*` methods |
| 215 * only ever make a copy, or read from this map after it has been set in | 219 * should only ever make a copy, or read from this map after it has been set |
| 216 * [visitClassDeclaration]. | 220 * in [visitClassDeclaration]. |
| 217 * | 221 * |
| 218 * See [visitClassDeclaration], and [_checkForAllFinalInitializedErrorCodes]. | 222 * See [visitClassDeclaration], and [_checkForAllFinalInitializedErrorCodes]. |
| 219 */ | 223 */ |
| 220 HashMap<FieldElement, INIT_STATE> _initialFieldElementsMap; | 224 HashMap<FieldElement, INIT_STATE> _initialFieldElementsMap; |
| 221 | 225 |
| 222 /** | 226 /** |
| 223 * A table mapping name of the library to the export directive which export th
is library. | 227 * A table mapping name of the library to the export directive which export |
| 228 * this library. |
| 224 */ | 229 */ |
| 225 HashMap<String, LibraryElement> _nameToExportElement = | 230 HashMap<String, LibraryElement> _nameToExportElement = |
| 226 new HashMap<String, LibraryElement>(); | 231 new HashMap<String, LibraryElement>(); |
| 227 | 232 |
| 228 /** | 233 /** |
| 229 * A table mapping name of the library to the import directive which import th
is library. | 234 * A table mapping name of the library to the import directive which import |
| 235 * this library. |
| 230 */ | 236 */ |
| 231 HashMap<String, LibraryElement> _nameToImportElement = | 237 HashMap<String, LibraryElement> _nameToImportElement = |
| 232 new HashMap<String, LibraryElement>(); | 238 new HashMap<String, LibraryElement>(); |
| 233 | 239 |
| 234 /** | 240 /** |
| 235 * A table mapping names to the exported elements. | 241 * A table mapping names to the exported elements. |
| 236 */ | 242 */ |
| 237 HashMap<String, Element> _exportedElements = new HashMap<String, Element>(); | 243 HashMap<String, Element> _exportedElements = new HashMap<String, Element>(); |
| 238 | 244 |
| 239 /** | 245 /** |
| 240 * A set of the names of the variable initializers we are visiting now. | 246 * A set of the names of the variable initializers we are visiting now. |
| 241 */ | 247 */ |
| 242 HashSet<String> _namesForReferenceToDeclaredVariableInInitializer = | 248 HashSet<String> _namesForReferenceToDeclaredVariableInInitializer = |
| 243 new HashSet<String>(); | 249 new HashSet<String>(); |
| 244 | 250 |
| 245 /** | 251 /** |
| 246 * A list of types used by the [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]
and | 252 * A list of types used by the [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS] |
| 247 * [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS] error codes. | 253 * and [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS] error codes. |
| 248 */ | 254 */ |
| 249 List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT; | 255 List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT; |
| 250 | 256 |
| 251 /** | 257 /** |
| 252 * Initialize the [ErrorVerifier] visitor. | 258 * Initialize a newly created error verifier. |
| 253 */ | 259 */ |
| 254 ErrorVerifier(this._errorReporter, this._currentLibrary, this._typeProvider, | 260 ErrorVerifier(this._errorReporter, this._currentLibrary, this._typeProvider, |
| 255 this._inheritanceManager) { | 261 this._inheritanceManager) { |
| 256 this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary; | 262 this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary; |
| 257 this._hasExtUri = _currentLibrary.hasExtUri; | 263 this._hasExtUri = _currentLibrary.hasExtUri; |
| 258 _isEnclosingConstructorConst = false; | 264 _isEnclosingConstructorConst = false; |
| 259 _isInCatchClause = false; | 265 _isInCatchClause = false; |
| 260 _isInStaticVariableDeclaration = false; | 266 _isInStaticVariableDeclaration = false; |
| 261 _isInInstanceVariableDeclaration = false; | 267 _isInInstanceVariableDeclaration = false; |
| 262 _isInInstanceVariableInitializer = false; | 268 _isInInstanceVariableInitializer = false; |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 _isInNativeClass = false; | 439 _isInNativeClass = false; |
| 434 _initialFieldElementsMap = null; | 440 _initialFieldElementsMap = null; |
| 435 _enclosingClass = outerClass; | 441 _enclosingClass = outerClass; |
| 436 } | 442 } |
| 437 } | 443 } |
| 438 | 444 |
| 439 /** | 445 /** |
| 440 * Implementation of this method should be synchronized with | 446 * Implementation of this method should be synchronized with |
| 441 * [visitClassDeclaration]. | 447 * [visitClassDeclaration]. |
| 442 */ | 448 */ |
| 443 visitClassDeclarationIncrementally(ClassDeclaration node) { | 449 void visitClassDeclarationIncrementally(ClassDeclaration node) { |
| 444 _isInNativeClass = node.nativeClause != null; | 450 _isInNativeClass = node.nativeClause != null; |
| 445 _enclosingClass = node.element; | 451 _enclosingClass = node.element; |
| 446 // initialize initialFieldElementsMap | 452 // initialize initialFieldElementsMap |
| 447 if (_enclosingClass != null) { | 453 if (_enclosingClass != null) { |
| 448 List<FieldElement> fieldElements = _enclosingClass.fields; | 454 List<FieldElement> fieldElements = _enclosingClass.fields; |
| 449 _initialFieldElementsMap = new HashMap<FieldElement, INIT_STATE>(); | 455 _initialFieldElementsMap = new HashMap<FieldElement, INIT_STATE>(); |
| 450 for (FieldElement fieldElement in fieldElements) { | 456 for (FieldElement fieldElement in fieldElements) { |
| 451 if (!fieldElement.isSynthetic) { | 457 if (!fieldElement.isSynthetic) { |
| 452 _initialFieldElementsMap[fieldElement] = fieldElement.initializer == | 458 _initialFieldElementsMap[fieldElement] = fieldElement.initializer == |
| 453 null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; | 459 null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; |
| (...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1084 errorCode = CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR; | 1090 errorCode = CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR; |
| 1085 } else { | 1091 } else { |
| 1086 errorCode = CompileTimeErrorCode.YIELD_IN_NON_GENERATOR; | 1092 errorCode = CompileTimeErrorCode.YIELD_IN_NON_GENERATOR; |
| 1087 } | 1093 } |
| 1088 _errorReporter.reportErrorForNode(errorCode, node); | 1094 _errorReporter.reportErrorForNode(errorCode, node); |
| 1089 } | 1095 } |
| 1090 return super.visitYieldStatement(node); | 1096 return super.visitYieldStatement(node); |
| 1091 } | 1097 } |
| 1092 | 1098 |
| 1093 /** | 1099 /** |
| 1094 * This verifies if the passed map literal has type arguments then there is ex
actly two. | 1100 * Verify that the given list of [typeArguments] contains exactly two |
| 1101 * elements. |
| 1095 * | 1102 * |
| 1096 * @param typeArguments the type arguments, always non-`null` | |
| 1097 * @return `true` if and only if an error code is generated on the passed node | |
| 1098 * See [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]. | 1103 * See [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]. |
| 1099 */ | 1104 */ |
| 1100 bool _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { | 1105 bool _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { |
| 1101 // check number of type arguments | 1106 // check number of type arguments |
| 1102 int num = typeArguments.arguments.length; | 1107 int num = typeArguments.arguments.length; |
| 1103 if (num == 2) { | 1108 if (num == 2) { |
| 1104 return false; | 1109 return false; |
| 1105 } | 1110 } |
| 1106 // report problem | 1111 // report problem |
| 1107 _errorReporter.reportErrorForNode( | 1112 _errorReporter.reportErrorForNode( |
| 1108 StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArguments, | 1113 StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArguments, |
| 1109 [num]); | 1114 [num]); |
| 1110 return true; | 1115 return true; |
| 1111 } | 1116 } |
| 1112 | 1117 |
| 1113 /** | 1118 /** |
| 1114 * This verifies that the passed constructor declaration does not violate any
of the error codes | 1119 * Verify that the given [constructor] declaration does not violate any of the |
| 1115 * relating to the initialization of fields in the enclosing class. | 1120 * error codes relating to the initialization of fields in the enclosing |
| 1121 * class. |
| 1116 * | 1122 * |
| 1117 * @param node the [ConstructorDeclaration] to evaluate | |
| 1118 * @return `true` if and only if an error code is generated on the passed node | |
| 1119 * See [_initialFieldElementsMap], | 1123 * See [_initialFieldElementsMap], |
| 1120 * [StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR], | 1124 * [StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR], and |
| 1121 * and [CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES]. | 1125 * [CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES]. |
| 1122 */ | 1126 */ |
| 1123 bool _checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) { | 1127 bool _checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) { |
| 1124 if (node.factoryKeyword != null || | 1128 if (node.factoryKeyword != null || |
| 1125 node.redirectedConstructor != null || | 1129 node.redirectedConstructor != null || |
| 1126 node.externalKeyword != null) { | 1130 node.externalKeyword != null) { |
| 1127 return false; | 1131 return false; |
| 1128 } | 1132 } |
| 1129 // Ignore if native class. | 1133 // Ignore if native class. |
| 1130 if (_isInNativeClass) { | 1134 if (_isInNativeClass) { |
| 1131 return false; | 1135 return false; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1245 ]); | 1249 ]); |
| 1246 } | 1250 } |
| 1247 analysisError.setProperty( | 1251 analysisError.setProperty( |
| 1248 ErrorProperty.NOT_INITIALIZED_FIELDS, notInitFinalFields); | 1252 ErrorProperty.NOT_INITIALIZED_FIELDS, notInitFinalFields); |
| 1249 _errorReporter.reportError(analysisError); | 1253 _errorReporter.reportError(analysisError); |
| 1250 } | 1254 } |
| 1251 return foundError; | 1255 return foundError; |
| 1252 } | 1256 } |
| 1253 | 1257 |
| 1254 /** | 1258 /** |
| 1255 * This checks the passed executable element against override-error codes. | 1259 * Check the given [executableElement] against override-error codes. The |
| 1260 * [overriddenExecutable] is the element that the executable element is |
| 1261 * overriding. The [parameters] is the parameters of the executable element. |
| 1262 * The [errorNameTarget] is the node to report problems on. |
| 1256 * | 1263 * |
| 1257 * @param executableElement a non-null [ExecutableElement] to evaluate | |
| 1258 * @param overriddenExecutable the element that the executableElement is overr
iding | |
| 1259 * @param parameters the parameters of the executable element | |
| 1260 * @param errorNameTarget the node to report problems on | |
| 1261 * @return `true` if and only if an error code is generated on the passed node | |
| 1262 * See [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
], | 1264 * See [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
], |
| 1263 * [CompileTimeErrorCode.INVALID_OVERRIDE_REQUIRED], | 1265 * [CompileTimeErrorCode.INVALID_OVERRIDE_REQUIRED], |
| 1264 * [CompileTimeErrorCode.INVALID_OVERRIDE_POSITIONAL], | 1266 * [CompileTimeErrorCode.INVALID_OVERRIDE_POSITIONAL], |
| 1265 * [CompileTimeErrorCode.INVALID_OVERRIDE_NAMED], | 1267 * [CompileTimeErrorCode.INVALID_OVERRIDE_NAMED], |
| 1266 * [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE], | 1268 * [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE], |
| 1267 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE], | 1269 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE], |
| 1268 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE], | 1270 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE], |
| 1269 * [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE], | 1271 * [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE], |
| 1270 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE], | 1272 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE], |
| 1271 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE], and | 1273 * [StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE], and |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1410 overridingType, | 1412 overridingType, |
| 1411 overriddenType, | 1413 overriddenType, |
| 1412 overriddenExecutable.enclosingElement.displayName | 1414 overriddenExecutable.enclosingElement.displayName |
| 1413 ]); | 1415 ]); |
| 1414 return true; | 1416 return true; |
| 1415 } | 1417 } |
| 1416 } | 1418 } |
| 1417 } | 1419 } |
| 1418 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES | 1420 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES |
| 1419 // | 1421 // |
| 1420 // Create three arrays: an array of the optional parameter ASTs | 1422 // Create three lists: a list of the optional parameter ASTs |
| 1421 // (FormalParameters), an array of the optional parameters elements from our | 1423 // (FormalParameters), a list of the optional parameters elements from our |
| 1422 // method, and finally an array of the optional parameter elements from the | 1424 // method, and finally a list of the optional parameter elements from the |
| 1423 // method we are overriding. | 1425 // method we are overriding. |
| 1424 // | 1426 // |
| 1425 bool foundError = false; | 1427 bool foundError = false; |
| 1426 List<AstNode> formalParameters = new List<AstNode>(); | 1428 List<AstNode> formalParameters = new List<AstNode>(); |
| 1427 List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>(); | 1429 List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>(); |
| 1428 List<ParameterElementImpl> overriddenParameterElts = | 1430 List<ParameterElementImpl> overriddenParameterElts = |
| 1429 new List<ParameterElementImpl>(); | 1431 new List<ParameterElementImpl>(); |
| 1430 List<ParameterElement> overriddenPEs = overriddenExecutable.parameters; | 1432 List<ParameterElement> overriddenPEs = overriddenExecutable.parameters; |
| 1431 for (int i = 0; i < parameters.length; i++) { | 1433 for (int i = 0; i < parameters.length; i++) { |
| 1432 ParameterElement parameter = parameters[i]; | 1434 ParameterElement parameter = parameters[i]; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1520 ]); | 1522 ]); |
| 1521 foundError = true; | 1523 foundError = true; |
| 1522 } | 1524 } |
| 1523 } | 1525 } |
| 1524 } | 1526 } |
| 1525 } | 1527 } |
| 1526 return foundError; | 1528 return foundError; |
| 1527 } | 1529 } |
| 1528 | 1530 |
| 1529 /** | 1531 /** |
| 1530 * This checks the passed executable element against override-error codes. Thi
s method computes | 1532 * Check the given [executableElement] against override-error codes. This |
| 1531 * the passed executableElement is overriding and calls | 1533 * method computes the given executableElement is overriding and calls |
| 1532 * [checkForAllInvalidOverrideErrorCodes] | 1534 * [_checkForAllInvalidOverrideErrorCodes] when the [InheritanceManager] |
| 1533 * when the [InheritanceManager] returns a [MultiplyInheritedExecutableElement
], this | 1535 * returns a [MultiplyInheritedExecutableElement], this method loops through |
| 1534 * method loops through the array in the [MultiplyInheritedExecutableElement]. | 1536 * the list in the [MultiplyInheritedExecutableElement]. The [parameters] are |
| 1535 * | 1537 * the parameters of the executable element. The [errorNameTarget] is the node |
| 1536 * @param executableElement a non-null [ExecutableElement] to evaluate | 1538 * to report problems on. |
| 1537 * @param parameters the parameters of the executable element | |
| 1538 * @param errorNameTarget the node to report problems on | |
| 1539 * @return `true` if and only if an error code is generated on the passed node | |
| 1540 */ | 1539 */ |
| 1541 bool _checkForAllInvalidOverrideErrorCodesForExecutable( | 1540 bool _checkForAllInvalidOverrideErrorCodesForExecutable( |
| 1542 ExecutableElement executableElement, List<ParameterElement> parameters, | 1541 ExecutableElement executableElement, List<ParameterElement> parameters, |
| 1543 List<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) { | 1542 List<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) { |
| 1544 // | 1543 // |
| 1545 // Compute the overridden executable from the InheritanceManager | 1544 // Compute the overridden executable from the InheritanceManager |
| 1546 // | 1545 // |
| 1547 List<ExecutableElement> overriddenExecutables = _inheritanceManager | 1546 List<ExecutableElement> overriddenExecutables = _inheritanceManager |
| 1548 .lookupOverrides(_enclosingClass, executableElement.name); | 1547 .lookupOverrides(_enclosingClass, executableElement.name); |
| 1549 if (_checkForInstanceMethodNameCollidesWithSuperclassStatic( | 1548 if (_checkForInstanceMethodNameCollidesWithSuperclassStatic( |
| 1550 executableElement, errorNameTarget)) { | 1549 executableElement, errorNameTarget)) { |
| 1551 return true; | 1550 return true; |
| 1552 } | 1551 } |
| 1553 for (ExecutableElement overriddenElement in overriddenExecutables) { | 1552 for (ExecutableElement overriddenElement in overriddenExecutables) { |
| 1554 if (_checkForAllInvalidOverrideErrorCodes(executableElement, | 1553 if (_checkForAllInvalidOverrideErrorCodes(executableElement, |
| 1555 overriddenElement, parameters, parameterLocations, errorNameTarget)) { | 1554 overriddenElement, parameters, parameterLocations, errorNameTarget)) { |
| 1556 return true; | 1555 return true; |
| 1557 } | 1556 } |
| 1558 } | 1557 } |
| 1559 return false; | 1558 return false; |
| 1560 } | 1559 } |
| 1561 | 1560 |
| 1562 /** | 1561 /** |
| 1563 * This checks the passed field declaration against override-error codes. | 1562 * Check the given [field] declaration against override-error codes. |
| 1564 * | 1563 * |
| 1565 * @param node the [MethodDeclaration] to evaluate | |
| 1566 * @return `true` if and only if an error code is generated on the passed node | |
| 1567 * See [_checkForAllInvalidOverrideErrorCodes]. | 1564 * See [_checkForAllInvalidOverrideErrorCodes]. |
| 1568 */ | 1565 */ |
| 1569 bool _checkForAllInvalidOverrideErrorCodesForField(FieldDeclaration node) { | 1566 bool _checkForAllInvalidOverrideErrorCodesForField(FieldDeclaration node) { |
| 1570 if (_enclosingClass == null || node.isStatic) { | 1567 if (_enclosingClass == null || node.isStatic) { |
| 1571 return false; | 1568 return false; |
| 1572 } | 1569 } |
| 1573 bool hasProblems = false; | 1570 bool hasProblems = false; |
| 1574 VariableDeclarationList fields = node.fields; | 1571 VariableDeclarationList fields = node.fields; |
| 1575 for (VariableDeclaration field in fields.variables) { | 1572 for (VariableDeclaration field in fields.variables) { |
| 1576 FieldElement element = field.element as FieldElement; | 1573 FieldElement element = field.element as FieldElement; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1590 if (_checkForAllInvalidOverrideErrorCodesForExecutable( | 1587 if (_checkForAllInvalidOverrideErrorCodesForExecutable( |
| 1591 setter, setter.parameters, <AstNode>[fieldName], fieldName)) { | 1588 setter, setter.parameters, <AstNode>[fieldName], fieldName)) { |
| 1592 hasProblems = true; | 1589 hasProblems = true; |
| 1593 } | 1590 } |
| 1594 } | 1591 } |
| 1595 } | 1592 } |
| 1596 return hasProblems; | 1593 return hasProblems; |
| 1597 } | 1594 } |
| 1598 | 1595 |
| 1599 /** | 1596 /** |
| 1600 * This checks the passed method declaration against override-error codes. | 1597 * Check the given [method] declaration against override-error codes. |
| 1601 * | 1598 * |
| 1602 * @param node the [MethodDeclaration] to evaluate | |
| 1603 * @return `true` if and only if an error code is generated on the passed node | |
| 1604 * See [_checkForAllInvalidOverrideErrorCodes]. | 1599 * See [_checkForAllInvalidOverrideErrorCodes]. |
| 1605 */ | 1600 */ |
| 1606 bool _checkForAllInvalidOverrideErrorCodesForMethod(MethodDeclaration node) { | 1601 bool _checkForAllInvalidOverrideErrorCodesForMethod(MethodDeclaration node) { |
| 1607 if (_enclosingClass == null || | 1602 if (_enclosingClass == null || |
| 1608 node.isStatic || | 1603 node.isStatic || |
| 1609 node.body is NativeFunctionBody) { | 1604 node.body is NativeFunctionBody) { |
| 1610 return false; | 1605 return false; |
| 1611 } | 1606 } |
| 1612 ExecutableElement executableElement = node.element; | 1607 ExecutableElement executableElement = node.element; |
| 1613 if (executableElement == null) { | 1608 if (executableElement == null) { |
| 1614 return false; | 1609 return false; |
| 1615 } | 1610 } |
| 1616 SimpleIdentifier methodName = node.name; | 1611 SimpleIdentifier methodName = node.name; |
| 1617 if (methodName.isSynthetic) { | 1612 if (methodName.isSynthetic) { |
| 1618 return false; | 1613 return false; |
| 1619 } | 1614 } |
| 1620 FormalParameterList formalParameterList = node.parameters; | 1615 FormalParameterList formalParameterList = node.parameters; |
| 1621 NodeList<FormalParameter> parameterList = | 1616 NodeList<FormalParameter> parameterList = |
| 1622 formalParameterList != null ? formalParameterList.parameters : null; | 1617 formalParameterList != null ? formalParameterList.parameters : null; |
| 1623 List<AstNode> parameters = | 1618 List<AstNode> parameters = |
| 1624 parameterList != null ? new List.from(parameterList) : null; | 1619 parameterList != null ? new List.from(parameterList) : null; |
| 1625 return _checkForAllInvalidOverrideErrorCodesForExecutable(executableElement, | 1620 return _checkForAllInvalidOverrideErrorCodesForExecutable(executableElement, |
| 1626 executableElement.parameters, parameters, methodName); | 1621 executableElement.parameters, parameters, methodName); |
| 1627 } | 1622 } |
| 1628 | 1623 |
| 1629 /** | 1624 /** |
| 1630 * This verifies that all classes of the passed 'with' clause are valid. | 1625 * Verify that all classes of the given [withClause] are valid. |
| 1631 * | 1626 * |
| 1632 * @param node the 'with' clause to evaluate | |
| 1633 * @return `true` if and only if an error code is generated on the passed node | |
| 1634 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR], | 1627 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR], |
| 1635 * [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT], and | 1628 * [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT], and |
| 1636 * [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]. | 1629 * [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]. |
| 1637 */ | 1630 */ |
| 1638 bool _checkForAllMixinErrorCodes(WithClause withClause) { | 1631 bool _checkForAllMixinErrorCodes(WithClause withClause) { |
| 1639 if (withClause == null) { | 1632 if (withClause == null) { |
| 1640 return false; | 1633 return false; |
| 1641 } | 1634 } |
| 1642 bool problemReported = false; | 1635 bool problemReported = false; |
| 1643 for (TypeName mixinName in withClause.mixinTypes) { | 1636 for (TypeName mixinName in withClause.mixinTypes) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1662 } | 1655 } |
| 1663 if (_checkForMixinReferencesSuper(mixinName, mixinElement)) { | 1656 if (_checkForMixinReferencesSuper(mixinName, mixinElement)) { |
| 1664 problemReported = true; | 1657 problemReported = true; |
| 1665 } | 1658 } |
| 1666 } | 1659 } |
| 1667 } | 1660 } |
| 1668 return problemReported; | 1661 return problemReported; |
| 1669 } | 1662 } |
| 1670 | 1663 |
| 1671 /** | 1664 /** |
| 1672 * This checks error related to the redirected constructors. | 1665 * Check for errors related to the redirected constructors. |
| 1673 * | 1666 * |
| 1674 * @param node the constructor declaration to evaluate | |
| 1675 * @return `true` if and only if an error code is generated on the passed node | |
| 1676 * See [StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE], | 1667 * See [StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE], |
| 1677 * [StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE], and | 1668 * [StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE], and |
| 1678 * [StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR]. | 1669 * [StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR]. |
| 1679 */ | 1670 */ |
| 1680 bool _checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) { | 1671 bool _checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) { |
| 1681 // | 1672 // |
| 1682 // Prepare redirected constructor node | 1673 // Prepare redirected constructor node |
| 1683 // | 1674 // |
| 1684 ConstructorName redirectedConstructor = node.redirectedConstructor; | 1675 ConstructorName redirectedConstructor = node.redirectedConstructor; |
| 1685 if (redirectedConstructor == null) { | 1676 if (redirectedConstructor == null) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1736 if (!redirectedType.isSubtypeOf(constructorType)) { | 1727 if (!redirectedType.isSubtypeOf(constructorType)) { |
| 1737 _errorReporter.reportErrorForNode( | 1728 _errorReporter.reportErrorForNode( |
| 1738 StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE, | 1729 StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE, |
| 1739 redirectedConstructor, [redirectedType, constructorType]); | 1730 redirectedConstructor, [redirectedType, constructorType]); |
| 1740 return true; | 1731 return true; |
| 1741 } | 1732 } |
| 1742 return false; | 1733 return false; |
| 1743 } | 1734 } |
| 1744 | 1735 |
| 1745 /** | 1736 /** |
| 1746 * This checks that the return statement of the form <i>return e;</i> is not i
n a generative | 1737 * Check that the return [statement] of the form <i>return e;</i> is not in a |
| 1747 * constructor. | 1738 * generative constructor. |
| 1748 * | 1739 * |
| 1749 * This checks that return statements without expressions are not in a generat
ive constructor and | 1740 * Check that return statements without expressions are not in a generative |
| 1750 * the return type is not assignable to `null`; that is, we don't have `return
;` if | 1741 * constructor and the return type is not assignable to `null`; that is, we |
| 1751 * the enclosing method has a return type. | 1742 * don't have `return;` if the enclosing method has a return type. |
| 1752 * | 1743 * |
| 1753 * This checks that the return type matches the type of the declared return ty
pe in the enclosing | 1744 * Check that the return type matches the type of the declared return type in |
| 1754 * method or function. | 1745 * the enclosing method or function. |
| 1755 * | 1746 * |
| 1756 * @param node the return statement to evaluate | |
| 1757 * @return `true` if and only if an error code is generated on the passed node | |
| 1758 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR], | 1747 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR], |
| 1759 * [StaticWarningCode.RETURN_WITHOUT_VALUE], and | 1748 * [StaticWarningCode.RETURN_WITHOUT_VALUE], and |
| 1760 * [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. | 1749 * [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. |
| 1761 */ | 1750 */ |
| 1762 bool _checkForAllReturnStatementErrorCodes(ReturnStatement node) { | 1751 bool _checkForAllReturnStatementErrorCodes(ReturnStatement node) { |
| 1763 FunctionType functionType = | 1752 FunctionType functionType = |
| 1764 _enclosingFunction == null ? null : _enclosingFunction.type; | 1753 _enclosingFunction == null ? null : _enclosingFunction.type; |
| 1765 DartType expectedReturnType = functionType == null | 1754 DartType expectedReturnType = functionType == null |
| 1766 ? DynamicTypeImpl.instance | 1755 ? DynamicTypeImpl.instance |
| 1767 : functionType.returnType; | 1756 : functionType.returnType; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1792 } else if (_inGenerator) { | 1781 } else if (_inGenerator) { |
| 1793 // RETURN_IN_GENERATOR | 1782 // RETURN_IN_GENERATOR |
| 1794 _errorReporter.reportErrorForNode( | 1783 _errorReporter.reportErrorForNode( |
| 1795 CompileTimeErrorCode.RETURN_IN_GENERATOR, node); | 1784 CompileTimeErrorCode.RETURN_IN_GENERATOR, node); |
| 1796 } | 1785 } |
| 1797 // RETURN_OF_INVALID_TYPE | 1786 // RETURN_OF_INVALID_TYPE |
| 1798 return _checkForReturnOfInvalidType(returnExpression, expectedReturnType); | 1787 return _checkForReturnOfInvalidType(returnExpression, expectedReturnType); |
| 1799 } | 1788 } |
| 1800 | 1789 |
| 1801 /** | 1790 /** |
| 1802 * This verifies that the export namespace of the passed export directive does
not export any name | 1791 * Verify that the export namespace of the given export [directive] does not |
| 1803 * already exported by other export directive. | 1792 * export any name already exported by another export directive. The |
| 1793 * [exportElement] is the [ExportElement] retrieved from the node. If the |
| 1794 * element in the node was `null`, then this method is not called. The |
| 1795 * [exportedLibrary] is the library element containing the exported element. |
| 1804 * | 1796 * |
| 1805 * @param node the export directive node to report problem on | |
| 1806 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the | |
| 1807 * node was `null`, then this method is not called | |
| 1808 * @param exportedLibrary the library element containing the exported element | |
| 1809 * @return `true` if and only if an error code is generated on the passed node | |
| 1810 * See [CompileTimeErrorCode.AMBIGUOUS_EXPORT]. | 1797 * See [CompileTimeErrorCode.AMBIGUOUS_EXPORT]. |
| 1811 */ | 1798 */ |
| 1812 bool _checkForAmbiguousExport(ExportDirective node, | 1799 bool _checkForAmbiguousExport(ExportDirective node, |
| 1813 ExportElement exportElement, LibraryElement exportedLibrary) { | 1800 ExportElement exportElement, LibraryElement exportedLibrary) { |
| 1814 if (exportedLibrary == null) { | 1801 if (exportedLibrary == null) { |
| 1815 return false; | 1802 return false; |
| 1816 } | 1803 } |
| 1817 // check exported names | 1804 // check exported names |
| 1818 Namespace namespace = | 1805 Namespace namespace = |
| 1819 new NamespaceBuilder().createExportNamespaceForDirective(exportElement); | 1806 new NamespaceBuilder().createExportNamespaceForDirective(exportElement); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1830 ]); | 1817 ]); |
| 1831 return true; | 1818 return true; |
| 1832 } else { | 1819 } else { |
| 1833 _exportedElements[name] = element; | 1820 _exportedElements[name] = element; |
| 1834 } | 1821 } |
| 1835 } | 1822 } |
| 1836 return false; | 1823 return false; |
| 1837 } | 1824 } |
| 1838 | 1825 |
| 1839 /** | 1826 /** |
| 1840 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. | 1827 * Verify that the given [expression] can be assigned to its corresponding |
| 1828 * parameters. The [expectedStaticType] is the expected static type of the |
| 1829 * parameter. The [actualStaticType] is the actual static type of the |
| 1830 * argument. The [expectedPropagatedType] is the expected propagated type of |
| 1831 * the parameter, may be `null`. The [actualPropagatedType] is the expected |
| 1832 * propagated type of the parameter, may be `null`. |
| 1841 * | 1833 * |
| 1842 * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAss
ignable. | 1834 * This method corresponds to |
| 1835 * [BestPracticesVerifier.checkForArgumentTypeNotAssignable]. |
| 1843 * | 1836 * |
| 1844 * @param expression the expression to evaluate | |
| 1845 * @param expectedStaticType the expected static type of the parameter | |
| 1846 * @param actualStaticType the actual static type of the argument | |
| 1847 * @param expectedPropagatedType the expected propagated type of the parameter
, may be | |
| 1848 * `null` | |
| 1849 * @param actualPropagatedType the expected propagated type of the parameter,
may be `null` | |
| 1850 * @return `true` if and only if an error code is generated on the passed node | |
| 1851 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], | 1837 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], |
| 1852 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], | 1838 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], |
| 1853 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], | 1839 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], |
| 1854 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], | 1840 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], |
| 1855 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], | 1841 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], |
| 1856 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and | 1842 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and |
| 1857 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. | 1843 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. |
| 1858 */ | 1844 */ |
| 1859 bool _checkForArgumentTypeNotAssignable(Expression expression, | 1845 bool _checkForArgumentTypeNotAssignable(Expression expression, |
| 1860 DartType expectedStaticType, DartType actualStaticType, | 1846 DartType expectedStaticType, DartType actualStaticType, |
| 1861 ErrorCode errorCode) { | 1847 ErrorCode errorCode) { |
| 1862 // | 1848 // |
| 1863 // Warning case: test static type information | 1849 // Warning case: test static type information |
| 1864 // | 1850 // |
| 1865 if (actualStaticType != null && expectedStaticType != null) { | 1851 if (actualStaticType != null && expectedStaticType != null) { |
| 1866 if (!actualStaticType.isAssignableTo(expectedStaticType)) { | 1852 if (!actualStaticType.isAssignableTo(expectedStaticType)) { |
| 1867 _errorReporter.reportTypeErrorForNode( | 1853 _errorReporter.reportTypeErrorForNode( |
| 1868 errorCode, expression, [actualStaticType, expectedStaticType]); | 1854 errorCode, expression, [actualStaticType, expectedStaticType]); |
| 1869 return true; | 1855 return true; |
| 1870 } | 1856 } |
| 1871 } | 1857 } |
| 1872 return false; | 1858 return false; |
| 1873 } | 1859 } |
| 1874 | 1860 |
| 1875 /** | 1861 /** |
| 1876 * This verifies that the passed argument can be assigned to its corresponding
parameter. | 1862 * Verify that the given [argument] can be assigned to its corresponding |
| 1863 * parameter. |
| 1877 * | 1864 * |
| 1878 * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAss
ignableForArgument. | 1865 * This method corresponds to |
| 1866 * [BestPracticesVerifier.checkForArgumentTypeNotAssignableForArgument]. |
| 1879 * | 1867 * |
| 1880 * @param argument the argument to evaluate | |
| 1881 * @return `true` if and only if an error code is generated on the passed node | |
| 1882 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. | 1868 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. |
| 1883 */ | 1869 */ |
| 1884 bool _checkForArgumentTypeNotAssignableForArgument(Expression argument) { | 1870 bool _checkForArgumentTypeNotAssignableForArgument(Expression argument) { |
| 1885 if (argument == null) { | 1871 if (argument == null) { |
| 1886 return false; | 1872 return false; |
| 1887 } | 1873 } |
| 1888 ParameterElement staticParameterElement = argument.staticParameterElement; | 1874 ParameterElement staticParameterElement = argument.staticParameterElement; |
| 1889 DartType staticParameterType = | 1875 DartType staticParameterType = |
| 1890 staticParameterElement == null ? null : staticParameterElement.type; | 1876 staticParameterElement == null ? null : staticParameterElement.type; |
| 1891 return _checkForArgumentTypeNotAssignableWithExpectedTypes(argument, | 1877 return _checkForArgumentTypeNotAssignableWithExpectedTypes(argument, |
| 1892 staticParameterType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); | 1878 staticParameterType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); |
| 1893 } | 1879 } |
| 1894 | 1880 |
| 1895 /** | 1881 /** |
| 1896 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. | 1882 * Verify that the given [expression] can be assigned to its corresponding |
| 1883 * parameters. The [expectedStaticType] is the expected static type. The |
| 1884 * [expectedPropagatedType] is the expected propagated type, may be `null`. |
| 1897 * | 1885 * |
| 1898 * This method corresponds to | 1886 * This method corresponds to |
| 1899 * BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes. | 1887 * [BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes]. |
| 1900 * | 1888 * |
| 1901 * @param expression the expression to evaluate | |
| 1902 * @param expectedStaticType the expected static type | |
| 1903 * @param expectedPropagatedType the expected propagated type, may be `null` | |
| 1904 * @return `true` if and only if an error code is generated on the passed node | |
| 1905 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], | 1889 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], |
| 1906 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], | 1890 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], |
| 1907 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], | 1891 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], |
| 1908 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], | 1892 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], |
| 1909 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], | 1893 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], |
| 1910 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and | 1894 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and |
| 1911 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. | 1895 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. |
| 1912 */ | 1896 */ |
| 1913 bool _checkForArgumentTypeNotAssignableWithExpectedTypes( | 1897 bool _checkForArgumentTypeNotAssignableWithExpectedTypes( |
| 1914 Expression expression, DartType expectedStaticType, | 1898 Expression expression, DartType expectedStaticType, |
| 1915 ErrorCode errorCode) => _checkForArgumentTypeNotAssignable( | 1899 ErrorCode errorCode) => _checkForArgumentTypeNotAssignable( |
| 1916 expression, expectedStaticType, getStaticType(expression), errorCode); | 1900 expression, expectedStaticType, getStaticType(expression), errorCode); |
| 1917 | 1901 |
| 1918 /** | 1902 /** |
| 1919 * This verifies that the passed arguments can be assigned to their correspond
ing parameters. | 1903 * Verify that the arguments in the given [argumentList] can be assigned to |
| 1904 * their corresponding parameters. |
| 1920 * | 1905 * |
| 1921 * This method corresponds to BestPracticesVerifier.checkForArgumentTypesNotAs
signableInList. | 1906 * This method corresponds to |
| 1907 * [BestPracticesVerifier.checkForArgumentTypesNotAssignableInList]. |
| 1922 * | 1908 * |
| 1923 * @param node the arguments to evaluate | |
| 1924 * @return `true` if and only if an error code is generated on the passed node | |
| 1925 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. | 1909 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. |
| 1926 */ | 1910 */ |
| 1927 bool _checkForArgumentTypesNotAssignableInList(ArgumentList argumentList) { | 1911 bool _checkForArgumentTypesNotAssignableInList(ArgumentList argumentList) { |
| 1928 if (argumentList == null) { | 1912 if (argumentList == null) { |
| 1929 return false; | 1913 return false; |
| 1930 } | 1914 } |
| 1931 bool problemReported = false; | 1915 bool problemReported = false; |
| 1932 for (Expression argument in argumentList.arguments) { | 1916 for (Expression argument in argumentList.arguments) { |
| 1933 if (_checkForArgumentTypeNotAssignableForArgument(argument)) { | 1917 if (_checkForArgumentTypeNotAssignableForArgument(argument)) { |
| 1934 problemReported = true; | 1918 problemReported = true; |
| 1935 } | 1919 } |
| 1936 } | 1920 } |
| 1937 return problemReported; | 1921 return problemReported; |
| 1938 } | 1922 } |
| 1939 | 1923 |
| 1940 /** | 1924 /** |
| 1941 * Check that the static type of the given expression is assignable to the giv
en type. If it | 1925 * Check that the static type of the given expression is assignable to the |
| 1942 * isn't, report an error with the given error code. | 1926 * given type. If it isn't, report an error with the given error code. The |
| 1943 * | 1927 * [type] is the type that the expression must be assignable to. The |
| 1944 * @param expression the expression being tested | 1928 * [errorCode] is the error code to be reported. The [arguments] are the |
| 1945 * @param type the type that the expression must be assignable to | 1929 * arguments to pass in when creating the error. |
| 1946 * @param errorCode the error code to be reported | |
| 1947 * @param arguments the arguments to pass in when creating the error | |
| 1948 * @return `true` if an error was reported | |
| 1949 */ | 1930 */ |
| 1950 bool _checkForAssignability(Expression expression, InterfaceType type, | 1931 bool _checkForAssignability(Expression expression, InterfaceType type, |
| 1951 ErrorCode errorCode, List<Object> arguments) { | 1932 ErrorCode errorCode, List<Object> arguments) { |
| 1952 if (expression == null) { | 1933 if (expression == null) { |
| 1953 return false; | 1934 return false; |
| 1954 } | 1935 } |
| 1955 DartType expressionType = expression.staticType; | 1936 DartType expressionType = expression.staticType; |
| 1956 if (expressionType == null) { | 1937 if (expressionType == null) { |
| 1957 return false; | 1938 return false; |
| 1958 } | 1939 } |
| 1959 if (expressionType.isAssignableTo(type)) { | 1940 if (expressionType.isAssignableTo(type)) { |
| 1960 return false; | 1941 return false; |
| 1961 } | 1942 } |
| 1962 _errorReporter.reportErrorForNode(errorCode, expression, arguments); | 1943 _errorReporter.reportErrorForNode(errorCode, expression, arguments); |
| 1963 return true; | 1944 return true; |
| 1964 } | 1945 } |
| 1965 | 1946 |
| 1966 /** | 1947 /** |
| 1967 * This verifies that the passed expression is not final. | 1948 * Verify that the given [expression] is not final. |
| 1968 * | 1949 * |
| 1969 * @param node the expression to evaluate | |
| 1970 * @return `true` if and only if an error code is generated on the passed node | |
| 1971 * See [StaticWarningCode.ASSIGNMENT_TO_CONST], | 1950 * See [StaticWarningCode.ASSIGNMENT_TO_CONST], |
| 1972 * [StaticWarningCode.ASSIGNMENT_TO_FINAL], and | 1951 * [StaticWarningCode.ASSIGNMENT_TO_FINAL], and |
| 1973 * [StaticWarningCode.ASSIGNMENT_TO_METHOD]. | 1952 * [StaticWarningCode.ASSIGNMENT_TO_METHOD]. |
| 1974 */ | 1953 */ |
| 1975 bool _checkForAssignmentToFinal(Expression expression) { | 1954 bool _checkForAssignmentToFinal(Expression expression) { |
| 1976 // prepare element | 1955 // prepare element |
| 1977 Element element = null; | 1956 Element element = null; |
| 1978 AstNode highlightedNode = expression; | 1957 AstNode highlightedNode = expression; |
| 1979 if (expression is Identifier) { | 1958 if (expression is Identifier) { |
| 1980 element = expression.staticElement; | 1959 element = expression.staticElement; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2019 } | 1998 } |
| 2020 if (element is MethodElement) { | 1999 if (element is MethodElement) { |
| 2021 _errorReporter.reportErrorForNode( | 2000 _errorReporter.reportErrorForNode( |
| 2022 StaticWarningCode.ASSIGNMENT_TO_METHOD, expression); | 2001 StaticWarningCode.ASSIGNMENT_TO_METHOD, expression); |
| 2023 return true; | 2002 return true; |
| 2024 } | 2003 } |
| 2025 return false; | 2004 return false; |
| 2026 } | 2005 } |
| 2027 | 2006 |
| 2028 /** | 2007 /** |
| 2029 * This verifies that the passed identifier is not a keyword, and generates th
e passed error code | 2008 * Verify that the given [identifier] is not a keyword, and generates the |
| 2030 * on the identifier if it is a keyword. | 2009 * given [errorCode] on the identifier if it is a keyword. |
| 2031 * | 2010 * |
| 2032 * @param identifier the identifier to check to ensure that it is not a keywor
d | |
| 2033 * @param errorCode if the passed identifier is a keyword then this error code
is created on the | |
| 2034 * identifier, the error code will be one of | |
| 2035 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME], | |
| 2036 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME]
or | |
| 2037 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME] | |
| 2038 * @return `true` if and only if an error code is generated on the passed node | |
| 2039 * See [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME], | 2011 * See [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME], |
| 2040 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME], and | 2012 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME], and |
| 2041 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]. | 2013 * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]. |
| 2042 */ | 2014 */ |
| 2043 bool _checkForBuiltInIdentifierAsName( | 2015 bool _checkForBuiltInIdentifierAsName( |
| 2044 SimpleIdentifier identifier, ErrorCode errorCode) { | 2016 SimpleIdentifier identifier, ErrorCode errorCode) { |
| 2045 sc.Token token = identifier.token; | 2017 sc.Token token = identifier.token; |
| 2046 if (token.type == sc.TokenType.KEYWORD) { | 2018 if (token.type == sc.TokenType.KEYWORD) { |
| 2047 _errorReporter.reportErrorForNode( | 2019 _errorReporter.reportErrorForNode( |
| 2048 errorCode, identifier, [identifier.name]); | 2020 errorCode, identifier, [identifier.name]); |
| 2049 return true; | 2021 return true; |
| 2050 } | 2022 } |
| 2051 return false; | 2023 return false; |
| 2052 } | 2024 } |
| 2053 | 2025 |
| 2054 /** | 2026 /** |
| 2055 * This verifies that the given switch case is terminated with 'break', 'conti
nue', 'return' or | 2027 * Verify that the given [switchCase] is terminated with 'break', 'continue', |
| 2056 * 'throw'. | 2028 * 'return' or 'throw'. |
| 2057 * | 2029 * |
| 2058 * @param node the switch case to evaluate | |
| 2059 * @return `true` if and only if an error code is generated on the passed node | |
| 2060 * see [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]. | 2030 * see [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]. |
| 2061 */ | 2031 */ |
| 2062 bool _checkForCaseBlockNotTerminated(SwitchCase node) { | 2032 bool _checkForCaseBlockNotTerminated(SwitchCase node) { |
| 2063 NodeList<Statement> statements = node.statements; | 2033 NodeList<Statement> statements = node.statements; |
| 2064 if (statements.isEmpty) { | 2034 if (statements.isEmpty) { |
| 2065 // fall-through without statements at all | 2035 // fall-through without statements at all |
| 2066 AstNode parent = node.parent; | 2036 AstNode parent = node.parent; |
| 2067 if (parent is SwitchStatement) { | 2037 if (parent is SwitchStatement) { |
| 2068 SwitchStatement switchStatement = parent; | 2038 SwitchStatement switchStatement = parent; |
| 2069 NodeList<SwitchMember> members = switchStatement.members; | 2039 NodeList<SwitchMember> members = switchStatement.members; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2089 } | 2059 } |
| 2090 } | 2060 } |
| 2091 } | 2061 } |
| 2092 // report error | 2062 // report error |
| 2093 _errorReporter.reportErrorForToken( | 2063 _errorReporter.reportErrorForToken( |
| 2094 StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, node.keyword); | 2064 StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, node.keyword); |
| 2095 return true; | 2065 return true; |
| 2096 } | 2066 } |
| 2097 | 2067 |
| 2098 /** | 2068 /** |
| 2099 * This verifies that the switch cases in the given switch statement is termin
ated with 'break', | 2069 * Verify that the switch cases in the given switch [statement] are terminated |
| 2100 * 'continue', 'return' or 'throw'. | 2070 * with 'break', 'continue', 'return' or 'throw'. |
| 2101 * | 2071 * |
| 2102 * @param node the switch statement containing the cases to be checked | |
| 2103 * @return `true` if and only if an error code is generated on the passed node | |
| 2104 * See [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]. | 2072 * See [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]. |
| 2105 */ | 2073 */ |
| 2106 bool _checkForCaseBlocksNotTerminated(SwitchStatement node) { | 2074 bool _checkForCaseBlocksNotTerminated(SwitchStatement node) { |
| 2107 bool foundError = false; | 2075 bool foundError = false; |
| 2108 NodeList<SwitchMember> members = node.members; | 2076 NodeList<SwitchMember> members = node.members; |
| 2109 int lastMember = members.length - 1; | 2077 int lastMember = members.length - 1; |
| 2110 for (int i = 0; i < lastMember; i++) { | 2078 for (int i = 0; i < lastMember; i++) { |
| 2111 SwitchMember member = members[i]; | 2079 SwitchMember member = members[i]; |
| 2112 if (member is SwitchCase && _checkForCaseBlockNotTerminated(member)) { | 2080 if (member is SwitchCase && _checkForCaseBlockNotTerminated(member)) { |
| 2113 foundError = true; | 2081 foundError = true; |
| 2114 } | 2082 } |
| 2115 } | 2083 } |
| 2116 return foundError; | 2084 return foundError; |
| 2117 } | 2085 } |
| 2118 | 2086 |
| 2119 /** | 2087 /** |
| 2120 * This verifies that the passed method declaration is abstract only if the en
closing class is | 2088 * Verify that the given [method] declaration is abstract only if the |
| 2121 * also abstract. | 2089 * enclosing class is also abstract. |
| 2122 * | 2090 * |
| 2123 * @param node the method declaration to evaluate | |
| 2124 * @return `true` if and only if an error code is generated on the passed node | |
| 2125 * See [StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER]. | 2091 * See [StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER]. |
| 2126 */ | 2092 */ |
| 2127 bool _checkForConcreteClassWithAbstractMember(MethodDeclaration node) { | 2093 bool _checkForConcreteClassWithAbstractMember(MethodDeclaration node) { |
| 2128 if (node.isAbstract && | 2094 if (node.isAbstract && |
| 2129 _enclosingClass != null && | 2095 _enclosingClass != null && |
| 2130 !_enclosingClass.isAbstract) { | 2096 !_enclosingClass.isAbstract) { |
| 2131 SimpleIdentifier nameNode = node.name; | 2097 SimpleIdentifier nameNode = node.name; |
| 2132 String memberName = nameNode.name; | 2098 String memberName = nameNode.name; |
| 2133 ExecutableElement overriddenMember; | 2099 ExecutableElement overriddenMember; |
| 2134 if (node.isGetter) { | 2100 if (node.isGetter) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2147 memberName, | 2113 memberName, |
| 2148 _enclosingClass.displayName | 2114 _enclosingClass.displayName |
| 2149 ]); | 2115 ]); |
| 2150 return true; | 2116 return true; |
| 2151 } | 2117 } |
| 2152 } | 2118 } |
| 2153 return false; | 2119 return false; |
| 2154 } | 2120 } |
| 2155 | 2121 |
| 2156 /** | 2122 /** |
| 2157 * This verifies all possible conflicts of the constructor name with other con
structors and | 2123 * Verify all possible conflicts of the given [constructor]'s name with other |
| 2158 * members of the same class. | 2124 * constructors and members of the same class. The [constructorElement] is the |
| 2125 * constructor's element. |
| 2159 * | 2126 * |
| 2160 * @param node the constructor declaration to evaluate | |
| 2161 * @param constructorElement the constructor element | |
| 2162 * @return `true` if and only if an error code is generated on the passed node | |
| 2163 * See [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT], | 2127 * See [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT], |
| 2164 * [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME], | 2128 * [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME], |
| 2165 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD], and | 2129 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD], and |
| 2166 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD]. | 2130 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD]. |
| 2167 */ | 2131 */ |
| 2168 bool _checkForConflictingConstructorNameAndMember( | 2132 bool _checkForConflictingConstructorNameAndMember( |
| 2169 ConstructorDeclaration node, ConstructorElement constructorElement) { | 2133 ConstructorDeclaration node, ConstructorElement constructorElement) { |
| 2170 SimpleIdentifier constructorName = node.name; | 2134 SimpleIdentifier constructorName = node.name; |
| 2171 String name = constructorElement.name; | 2135 String name = constructorElement.name; |
| 2172 ClassElement classElement = constructorElement.enclosingElement; | 2136 ClassElement classElement = constructorElement.enclosingElement; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2205 _errorReporter.reportErrorForNode( | 2169 _errorReporter.reportErrorForNode( |
| 2206 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, | 2170 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, |
| 2207 [name]); | 2171 [name]); |
| 2208 return true; | 2172 return true; |
| 2209 } | 2173 } |
| 2210 } | 2174 } |
| 2211 return false; | 2175 return false; |
| 2212 } | 2176 } |
| 2213 | 2177 |
| 2214 /** | 2178 /** |
| 2215 * This verifies that the [enclosingClass] does not have a method and getter p
air with the | 2179 * Verify that the [enclosingClass] does not have a method and getter pair |
| 2216 * same name on, via inheritance. | 2180 * with the same name on, via inheritance. |
| 2217 * | 2181 * |
| 2218 * @return `true` if and only if an error code is generated on the passed node | |
| 2219 * See [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD], and | 2182 * See [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD], and |
| 2220 * [CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER]. | 2183 * [CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER]. |
| 2221 */ | 2184 */ |
| 2222 bool _checkForConflictingGetterAndMethod() { | 2185 bool _checkForConflictingGetterAndMethod() { |
| 2223 if (_enclosingClass == null) { | 2186 if (_enclosingClass == null) { |
| 2224 return false; | 2187 return false; |
| 2225 } | 2188 } |
| 2226 bool hasProblem = false; | 2189 bool hasProblem = false; |
| 2227 // method declared in the enclosing class vs. inherited getter | 2190 // method declared in the enclosing class vs. inherited getter |
| 2228 for (MethodElement method in _enclosingClass.methods) { | 2191 for (MethodElement method in _enclosingClass.methods) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2263 _enclosingClass.displayName, | 2226 _enclosingClass.displayName, |
| 2264 inherited.enclosingElement.displayName, | 2227 inherited.enclosingElement.displayName, |
| 2265 name | 2228 name |
| 2266 ]); | 2229 ]); |
| 2267 } | 2230 } |
| 2268 // done | 2231 // done |
| 2269 return hasProblem; | 2232 return hasProblem; |
| 2270 } | 2233 } |
| 2271 | 2234 |
| 2272 /** | 2235 /** |
| 2273 * This verifies that the superclass of the [enclosingClass] does not declare
accessible | 2236 * Verify that the superclass of the [enclosingClass] does not declare |
| 2274 * static members with the same name as the instance getters/setters declared
in | 2237 * accessible static members with the same name as the instance |
| 2275 * [enclosingClass]. | 2238 * getters/setters declared in [enclosingClass]. |
| 2276 * | 2239 * |
| 2277 * @param node the method declaration to evaluate | |
| 2278 * @return `true` if and only if an error code is generated on the passed node | |
| 2279 * See [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER],
and | 2240 * See [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER],
and |
| 2280 * [StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER]. | 2241 * [StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER]. |
| 2281 */ | 2242 */ |
| 2282 bool _checkForConflictingInstanceGetterAndSuperclassMember() { | 2243 bool _checkForConflictingInstanceGetterAndSuperclassMember() { |
| 2283 if (_enclosingClass == null) { | 2244 if (_enclosingClass == null) { |
| 2284 return false; | 2245 return false; |
| 2285 } | 2246 } |
| 2286 InterfaceType enclosingType = _enclosingClass.type; | 2247 InterfaceType enclosingType = _enclosingClass.type; |
| 2287 // check every accessor | 2248 // check every accessor |
| 2288 bool hasProblem = false; | 2249 bool hasProblem = false; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2332 _errorReporter.reportErrorForElement( | 2293 _errorReporter.reportErrorForElement( |
| 2333 StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, | 2294 StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, |
| 2334 accessor, [superElementType.displayName]); | 2295 accessor, [superElementType.displayName]); |
| 2335 } | 2296 } |
| 2336 } | 2297 } |
| 2337 // done | 2298 // done |
| 2338 return hasProblem; | 2299 return hasProblem; |
| 2339 } | 2300 } |
| 2340 | 2301 |
| 2341 /** | 2302 /** |
| 2342 * This verifies that the enclosing class does not have a setter with the same
name as the passed | 2303 * Verify that the enclosing class does not have a setter with the same name |
| 2343 * instance method declaration. | 2304 * as the given instance method declaration. |
| 2344 * | 2305 * |
| 2345 * TODO(jwren) add other "conflicting" error codes into algorithm/ data struct
ure | 2306 * TODO(jwren) add other "conflicting" error codes into algorithm/ data |
| 2307 * structure. |
| 2346 * | 2308 * |
| 2347 * @param node the method declaration to evaluate | |
| 2348 * @return `true` if and only if an error code is generated on the passed node | |
| 2349 * See [StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER]. | 2309 * See [StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER]. |
| 2350 */ | 2310 */ |
| 2351 bool _checkForConflictingInstanceMethodSetter(ClassDeclaration node) { | 2311 bool _checkForConflictingInstanceMethodSetter(ClassDeclaration node) { |
| 2352 // Reference all of the class members in this class. | 2312 // Reference all of the class members in this class. |
| 2353 NodeList<ClassMember> classMembers = node.members; | 2313 NodeList<ClassMember> classMembers = node.members; |
| 2354 if (classMembers.isEmpty) { | 2314 if (classMembers.isEmpty) { |
| 2355 return false; | 2315 return false; |
| 2356 } | 2316 } |
| 2357 // Create a HashMap to track conflicting members, and then loop through | 2317 // Create a HashMap to track conflicting members, and then loop through |
| 2358 // members in the class to construct the HashMap, at the same time, | 2318 // members in the class to construct the HashMap, at the same time, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2429 } else { | 2389 } else { |
| 2430 memberHashMap[name.name] = method; | 2390 memberHashMap[name.name] = method; |
| 2431 } | 2391 } |
| 2432 } | 2392 } |
| 2433 } | 2393 } |
| 2434 } | 2394 } |
| 2435 return foundError; | 2395 return foundError; |
| 2436 } | 2396 } |
| 2437 | 2397 |
| 2438 /** | 2398 /** |
| 2439 * This verifies that the enclosing class does not have an instance member wit
h the same name as | 2399 * Verify that the enclosing class does not have an instance member with the |
| 2440 * the passed static getter method declaration. | 2400 * same name as the given static [method] declaration. |
| 2441 * | 2401 * |
| 2442 * @param node the method declaration to evaluate | |
| 2443 * @return `true` if and only if an error code is generated on the passed node | |
| 2444 * See [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]. | 2402 * See [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]. |
| 2445 */ | 2403 */ |
| 2446 bool _checkForConflictingStaticGetterAndInstanceSetter( | 2404 bool _checkForConflictingStaticGetterAndInstanceSetter( |
| 2447 MethodDeclaration node) { | 2405 MethodDeclaration node) { |
| 2448 if (!node.isStatic) { | 2406 if (!node.isStatic) { |
| 2449 return false; | 2407 return false; |
| 2450 } | 2408 } |
| 2451 // prepare name | 2409 // prepare name |
| 2452 SimpleIdentifier nameNode = node.name; | 2410 SimpleIdentifier nameNode = node.name; |
| 2453 if (nameNode == null) { | 2411 if (nameNode == null) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2473 ClassElement setterClass = setter.enclosingElement as ClassElement; | 2431 ClassElement setterClass = setter.enclosingElement as ClassElement; |
| 2474 InterfaceType setterType = setterClass.type; | 2432 InterfaceType setterType = setterClass.type; |
| 2475 // report problem | 2433 // report problem |
| 2476 _errorReporter.reportErrorForNode( | 2434 _errorReporter.reportErrorForNode( |
| 2477 StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER, | 2435 StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER, |
| 2478 nameNode, [setterType.displayName]); | 2436 nameNode, [setterType.displayName]); |
| 2479 return true; | 2437 return true; |
| 2480 } | 2438 } |
| 2481 | 2439 |
| 2482 /** | 2440 /** |
| 2483 * This verifies that the enclosing class does not have an instance member wit
h the same name as | 2441 * Verify that the enclosing class does not have an instance member with the |
| 2484 * the passed static getter method declaration. | 2442 * same name as the given static [method] declaration. |
| 2485 * | 2443 * |
| 2486 * @param node the method declaration to evaluate | |
| 2487 * @return `true` if and only if an error code is generated on the passed node | |
| 2488 * See [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]. | 2444 * See [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]. |
| 2489 */ | 2445 */ |
| 2490 bool _checkForConflictingStaticSetterAndInstanceMember( | 2446 bool _checkForConflictingStaticSetterAndInstanceMember( |
| 2491 MethodDeclaration node) { | 2447 MethodDeclaration node) { |
| 2492 if (!node.isStatic) { | 2448 if (!node.isStatic) { |
| 2493 return false; | 2449 return false; |
| 2494 } | 2450 } |
| 2495 // prepare name | 2451 // prepare name |
| 2496 SimpleIdentifier nameNode = node.name; | 2452 SimpleIdentifier nameNode = node.name; |
| 2497 if (nameNode == null) { | 2453 if (nameNode == null) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2523 ClassElement memberClass = member.enclosingElement as ClassElement; | 2479 ClassElement memberClass = member.enclosingElement as ClassElement; |
| 2524 InterfaceType memberType = memberClass.type; | 2480 InterfaceType memberType = memberClass.type; |
| 2525 // report problem | 2481 // report problem |
| 2526 _errorReporter.reportErrorForNode( | 2482 _errorReporter.reportErrorForNode( |
| 2527 StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER, | 2483 StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER, |
| 2528 nameNode, [memberType.displayName]); | 2484 nameNode, [memberType.displayName]); |
| 2529 return true; | 2485 return true; |
| 2530 } | 2486 } |
| 2531 | 2487 |
| 2532 /** | 2488 /** |
| 2533 * This verifies all conflicts between type variable and enclosing class. TODO
(scheglov) | 2489 * Verify all conflicts between type variable and enclosing class. |
| 2490 * TODO(scheglov) |
| 2534 * | 2491 * |
| 2535 * @param node the class declaration to evaluate | |
| 2536 * @return `true` if and only if an error code is generated on the passed node | |
| 2537 * See [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS], and | 2492 * See [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS], and |
| 2538 * [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]. | 2493 * [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]. |
| 2539 */ | 2494 */ |
| 2540 bool _checkForConflictingTypeVariableErrorCodes(ClassDeclaration node) { | 2495 bool _checkForConflictingTypeVariableErrorCodes(ClassDeclaration node) { |
| 2541 bool problemReported = false; | 2496 bool problemReported = false; |
| 2542 for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) { | 2497 for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) { |
| 2543 String name = typeParameter.name; | 2498 String name = typeParameter.name; |
| 2544 // name is same as the name of the enclosing class | 2499 // name is same as the name of the enclosing class |
| 2545 if (_enclosingClass.name == name) { | 2500 if (_enclosingClass.name == name) { |
| 2546 _errorReporter.reportErrorForOffset( | 2501 _errorReporter.reportErrorForOffset( |
| 2547 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, | 2502 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, |
| 2548 typeParameter.nameOffset, name.length, [name]); | 2503 typeParameter.nameOffset, name.length, [name]); |
| 2549 problemReported = true; | 2504 problemReported = true; |
| 2550 } | 2505 } |
| 2551 // check members | 2506 // check members |
| 2552 if (_enclosingClass.getMethod(name) != null || | 2507 if (_enclosingClass.getMethod(name) != null || |
| 2553 _enclosingClass.getGetter(name) != null || | 2508 _enclosingClass.getGetter(name) != null || |
| 2554 _enclosingClass.getSetter(name) != null) { | 2509 _enclosingClass.getSetter(name) != null) { |
| 2555 _errorReporter.reportErrorForOffset( | 2510 _errorReporter.reportErrorForOffset( |
| 2556 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER, | 2511 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER, |
| 2557 typeParameter.nameOffset, name.length, [name]); | 2512 typeParameter.nameOffset, name.length, [name]); |
| 2558 problemReported = true; | 2513 problemReported = true; |
| 2559 } | 2514 } |
| 2560 } | 2515 } |
| 2561 return problemReported; | 2516 return problemReported; |
| 2562 } | 2517 } |
| 2563 | 2518 |
| 2564 /** | 2519 /** |
| 2565 * This verifies that if the passed constructor declaration is 'const' then th
ere are no | 2520 * Verify that if the given [constructor] declaration is 'const' then there |
| 2566 * invocations of non-'const' super constructors. | 2521 * are no invocations of non-'const' super constructors. |
| 2567 * | 2522 * |
| 2568 * @param node the constructor declaration to evaluate | |
| 2569 * @return `true` if and only if an error code is generated on the passed node | |
| 2570 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]. | 2523 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]. |
| 2571 */ | 2524 */ |
| 2572 bool _checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) { | 2525 bool _checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) { |
| 2573 if (!_isEnclosingConstructorConst) { | 2526 if (!_isEnclosingConstructorConst) { |
| 2574 return false; | 2527 return false; |
| 2575 } | 2528 } |
| 2576 // OK, const factory, checked elsewhere | 2529 // OK, const factory, checked elsewhere |
| 2577 if (node.factoryKeyword != null) { | 2530 if (node.factoryKeyword != null) { |
| 2578 return false; | 2531 return false; |
| 2579 } | 2532 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2614 return false; | 2567 return false; |
| 2615 } | 2568 } |
| 2616 // default constructor is not 'const', report problem | 2569 // default constructor is not 'const', report problem |
| 2617 _errorReporter.reportErrorForNode( | 2570 _errorReporter.reportErrorForNode( |
| 2618 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, | 2571 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, |
| 2619 node.returnType, [supertype.displayName]); | 2572 node.returnType, [supertype.displayName]); |
| 2620 return true; | 2573 return true; |
| 2621 } | 2574 } |
| 2622 | 2575 |
| 2623 /** | 2576 /** |
| 2624 * This verifies that if the passed constructor declaration is 'const' then th
ere are no non-final | 2577 * Verify that if the given constructor [declaration] is 'const' then there |
| 2625 * instance variable. | 2578 * are no non-final instance variable. The [constructorElement] is the |
| 2579 * constructor element. |
| 2626 * | 2580 * |
| 2627 * @param node the constructor declaration to evaluate | |
| 2628 * @param constructorElement the constructor element | |
| 2629 * @return `true` if and only if an error code is generated on the passed node | |
| 2630 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]. | 2581 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]. |
| 2631 */ | 2582 */ |
| 2632 bool _checkForConstConstructorWithNonFinalField( | 2583 bool _checkForConstConstructorWithNonFinalField( |
| 2633 ConstructorDeclaration node, ConstructorElement constructorElement) { | 2584 ConstructorDeclaration node, ConstructorElement constructorElement) { |
| 2634 if (!_isEnclosingConstructorConst) { | 2585 if (!_isEnclosingConstructorConst) { |
| 2635 return false; | 2586 return false; |
| 2636 } | 2587 } |
| 2637 // check if there is non-final field | 2588 // check if there is non-final field |
| 2638 ClassElement classElement = constructorElement.enclosingElement; | 2589 ClassElement classElement = constructorElement.enclosingElement; |
| 2639 if (!classElement.hasNonFinalField) { | 2590 if (!classElement.hasNonFinalField) { |
| 2640 return false; | 2591 return false; |
| 2641 } | 2592 } |
| 2642 // report problem | 2593 // report problem |
| 2643 _errorReporter.reportErrorForNode( | 2594 _errorReporter.reportErrorForNode( |
| 2644 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, node); | 2595 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, node); |
| 2645 return true; | 2596 return true; |
| 2646 } | 2597 } |
| 2647 | 2598 |
| 2648 /** | 2599 /** |
| 2649 * This verifies that the passed 'const' instance creation expression is not c
reating a deferred | 2600 * Verify that the given 'const' instance creation [expression] is not |
| 2650 * type. | 2601 * creating a deferred type. The [constructorName] is the constructor name, |
| 2602 * always non-`null`. The [typeName] is the name of the type defining the |
| 2603 * constructor, always non-`null`. |
| 2651 * | 2604 * |
| 2652 * @param node the instance creation expression to evaluate | |
| 2653 * @param constructorName the constructor name, always non-`null` | |
| 2654 * @param typeName the name of the type defining the constructor, always non-`
null` | |
| 2655 * @return `true` if and only if an error code is generated on the passed node | |
| 2656 * See [CompileTimeErrorCode.CONST_DEFERRED_CLASS]. | 2605 * See [CompileTimeErrorCode.CONST_DEFERRED_CLASS]. |
| 2657 */ | 2606 */ |
| 2658 bool _checkForConstDeferredClass(InstanceCreationExpression node, | 2607 bool _checkForConstDeferredClass(InstanceCreationExpression node, |
| 2659 ConstructorName constructorName, TypeName typeName) { | 2608 ConstructorName constructorName, TypeName typeName) { |
| 2660 if (typeName.isDeferred) { | 2609 if (typeName.isDeferred) { |
| 2661 _errorReporter.reportErrorForNode( | 2610 _errorReporter.reportErrorForNode( |
| 2662 CompileTimeErrorCode.CONST_DEFERRED_CLASS, constructorName, | 2611 CompileTimeErrorCode.CONST_DEFERRED_CLASS, constructorName, |
| 2663 [typeName.name.name]); | 2612 [typeName.name.name]); |
| 2664 return true; | 2613 return true; |
| 2665 } | 2614 } |
| 2666 return false; | 2615 return false; |
| 2667 } | 2616 } |
| 2668 | 2617 |
| 2669 /** | 2618 /** |
| 2670 * This verifies that the passed throw expression is not enclosed in a 'const'
constructor | 2619 * Verify that the given throw [expression] is not enclosed in a 'const' |
| 2671 * declaration. | 2620 * constructor declaration. |
| 2672 * | 2621 * |
| 2673 * @param node the throw expression expression to evaluate | |
| 2674 * @return `true` if and only if an error code is generated on the passed node | |
| 2675 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION]. | 2622 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION]. |
| 2676 */ | 2623 */ |
| 2677 bool _checkForConstEvalThrowsException(ThrowExpression node) { | 2624 bool _checkForConstEvalThrowsException(ThrowExpression node) { |
| 2678 if (_isEnclosingConstructorConst) { | 2625 if (_isEnclosingConstructorConst) { |
| 2679 _errorReporter.reportErrorForNode( | 2626 _errorReporter.reportErrorForNode( |
| 2680 CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, node); | 2627 CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, node); |
| 2681 return true; | 2628 return true; |
| 2682 } | 2629 } |
| 2683 return false; | 2630 return false; |
| 2684 } | 2631 } |
| 2685 | 2632 |
| 2686 /** | 2633 /** |
| 2687 * This verifies that the passed normal formal parameter is not 'const'. | 2634 * Verify that the given normal formal [parameter] is not 'const'. |
| 2688 * | 2635 * |
| 2689 * @param node the normal formal parameter to evaluate | |
| 2690 * @return `true` if and only if an error code is generated on the passed node | |
| 2691 * See [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]. | 2636 * See [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]. |
| 2692 */ | 2637 */ |
| 2693 bool _checkForConstFormalParameter(NormalFormalParameter node) { | 2638 bool _checkForConstFormalParameter(NormalFormalParameter node) { |
| 2694 if (node.isConst) { | 2639 if (node.isConst) { |
| 2695 _errorReporter.reportErrorForNode( | 2640 _errorReporter.reportErrorForNode( |
| 2696 CompileTimeErrorCode.CONST_FORMAL_PARAMETER, node); | 2641 CompileTimeErrorCode.CONST_FORMAL_PARAMETER, node); |
| 2697 return true; | 2642 return true; |
| 2698 } | 2643 } |
| 2699 return false; | 2644 return false; |
| 2700 } | 2645 } |
| 2701 | 2646 |
| 2702 /** | 2647 /** |
| 2703 * This verifies that the passed instance creation expression is not being inv
oked on an abstract | 2648 * Verify that the given instance creation [expression] is not being invoked |
| 2704 * class. | 2649 * on an abstract class. The [typeName] is the [TypeName] of the |
| 2650 * [ConstructorName] from the [InstanceCreationExpression], this is the AST |
| 2651 * node that the error is attached to. The [type] is the type being |
| 2652 * constructed with this [InstanceCreationExpression]. |
| 2705 * | 2653 * |
| 2706 * @param node the instance creation expression to evaluate | |
| 2707 * @param typeName the [TypeName] of the [ConstructorName] from the | |
| 2708 * [InstanceCreationExpression], this is the AST node that the error
is attached to | |
| 2709 * @param type the type being constructed with this [InstanceCreationExpressio
n] | |
| 2710 * @return `true` if and only if an error code is generated on the passed node | |
| 2711 * See [StaticWarningCode.CONST_WITH_ABSTRACT_CLASS], and | 2654 * See [StaticWarningCode.CONST_WITH_ABSTRACT_CLASS], and |
| 2712 * [StaticWarningCode.NEW_WITH_ABSTRACT_CLASS]. | 2655 * [StaticWarningCode.NEW_WITH_ABSTRACT_CLASS]. |
| 2713 */ | 2656 */ |
| 2714 bool _checkForConstOrNewWithAbstractClass( | 2657 bool _checkForConstOrNewWithAbstractClass( |
| 2715 InstanceCreationExpression node, TypeName typeName, InterfaceType type) { | 2658 InstanceCreationExpression node, TypeName typeName, InterfaceType type) { |
| 2716 if (type.element.isAbstract) { | 2659 if (type.element.isAbstract) { |
| 2717 ConstructorElement element = node.staticElement; | 2660 ConstructorElement element = node.staticElement; |
| 2718 if (element != null && !element.isFactory) { | 2661 if (element != null && !element.isFactory) { |
| 2719 if ((node.keyword as sc.KeywordToken).keyword == sc.Keyword.CONST) { | 2662 if ((node.keyword as sc.KeywordToken).keyword == sc.Keyword.CONST) { |
| 2720 _errorReporter.reportErrorForNode( | 2663 _errorReporter.reportErrorForNode( |
| 2721 StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName); | 2664 StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName); |
| 2722 } else { | 2665 } else { |
| 2723 _errorReporter.reportErrorForNode( | 2666 _errorReporter.reportErrorForNode( |
| 2724 StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName); | 2667 StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName); |
| 2725 } | 2668 } |
| 2726 return true; | 2669 return true; |
| 2727 } | 2670 } |
| 2728 } | 2671 } |
| 2729 return false; | 2672 return false; |
| 2730 } | 2673 } |
| 2731 | 2674 |
| 2732 /** | 2675 /** |
| 2733 * This verifies that the passed instance creation expression is not being inv
oked on an enum. | 2676 * Verify that the given instance creation [expression] is not being invoked |
| 2677 * on an enum. The [typeName] is the [TypeName] of the [ConstructorName] from |
| 2678 * the [InstanceCreationExpression], this is the AST node that the error is |
| 2679 * attached to. The [type] is the type being constructed with this |
| 2680 * [InstanceCreationExpression]. |
| 2734 * | 2681 * |
| 2735 * @param node the instance creation expression to verify | |
| 2736 * @param typeName the [TypeName] of the [ConstructorName] from the | |
| 2737 * [InstanceCreationExpression], this is the AST node that the error
is attached to | |
| 2738 * @param type the type being constructed with this [InstanceCreationExpressio
n] | |
| 2739 * @return `true` if and only if an error code is generated on the passed node | |
| 2740 * See [CompileTimeErrorCode.INSTANTIATE_ENUM]. | 2682 * See [CompileTimeErrorCode.INSTANTIATE_ENUM]. |
| 2741 */ | 2683 */ |
| 2742 bool _checkForConstOrNewWithEnum( | 2684 bool _checkForConstOrNewWithEnum( |
| 2743 InstanceCreationExpression node, TypeName typeName, InterfaceType type) { | 2685 InstanceCreationExpression node, TypeName typeName, InterfaceType type) { |
| 2744 if (type.element.isEnum) { | 2686 if (type.element.isEnum) { |
| 2745 _errorReporter.reportErrorForNode( | 2687 _errorReporter.reportErrorForNode( |
| 2746 CompileTimeErrorCode.INSTANTIATE_ENUM, typeName); | 2688 CompileTimeErrorCode.INSTANTIATE_ENUM, typeName); |
| 2747 return true; | 2689 return true; |
| 2748 } | 2690 } |
| 2749 return false; | 2691 return false; |
| 2750 } | 2692 } |
| 2751 | 2693 |
| 2752 /** | 2694 /** |
| 2753 * This verifies that the passed 'const' instance creation expression is not b
eing invoked on a | 2695 * Verify that the given 'const' instance creation [expression] is not being |
| 2754 * constructor that is not 'const'. | 2696 * invoked on a constructor that is not 'const'. |
| 2755 * | 2697 * |
| 2756 * This method assumes that the instance creation was tested to be 'const' bef
ore being called. | 2698 * This method assumes that the instance creation was tested to be 'const' |
| 2699 * before being called. |
| 2757 * | 2700 * |
| 2758 * @param node the instance creation expression to verify | |
| 2759 * @return `true` if and only if an error code is generated on the passed node | |
| 2760 * See [CompileTimeErrorCode.CONST_WITH_NON_CONST]. | 2701 * See [CompileTimeErrorCode.CONST_WITH_NON_CONST]. |
| 2761 */ | 2702 */ |
| 2762 bool _checkForConstWithNonConst(InstanceCreationExpression node) { | 2703 bool _checkForConstWithNonConst(InstanceCreationExpression node) { |
| 2763 ConstructorElement constructorElement = node.staticElement; | 2704 ConstructorElement constructorElement = node.staticElement; |
| 2764 if (constructorElement != null && !constructorElement.isConst) { | 2705 if (constructorElement != null && !constructorElement.isConst) { |
| 2765 _errorReporter.reportErrorForNode( | 2706 _errorReporter.reportErrorForNode( |
| 2766 CompileTimeErrorCode.CONST_WITH_NON_CONST, node); | 2707 CompileTimeErrorCode.CONST_WITH_NON_CONST, node); |
| 2767 return true; | 2708 return true; |
| 2768 } | 2709 } |
| 2769 return false; | 2710 return false; |
| 2770 } | 2711 } |
| 2771 | 2712 |
| 2772 /** | 2713 /** |
| 2773 * This verifies that the passed type name does not reference any type paramet
ers. | 2714 * Verify that the given [typeName] does not reference any type parameters. |
| 2774 * | 2715 * |
| 2775 * @param typeName the type name to evaluate | |
| 2776 * @return `true` if and only if an error code is generated on the passed node | |
| 2777 * See [CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS]. | 2716 * See [CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS]. |
| 2778 */ | 2717 */ |
| 2779 bool _checkForConstWithTypeParameters(TypeName typeName) { | 2718 bool _checkForConstWithTypeParameters(TypeName typeName) { |
| 2780 // something wrong with AST | 2719 // something wrong with AST |
| 2781 if (typeName == null) { | 2720 if (typeName == null) { |
| 2782 return false; | 2721 return false; |
| 2783 } | 2722 } |
| 2784 Identifier name = typeName.name; | 2723 Identifier name = typeName.name; |
| 2785 if (name == null) { | 2724 if (name == null) { |
| 2786 return false; | 2725 return false; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2799 hasError = true; | 2738 hasError = true; |
| 2800 } | 2739 } |
| 2801 } | 2740 } |
| 2802 return hasError; | 2741 return hasError; |
| 2803 } | 2742 } |
| 2804 // OK | 2743 // OK |
| 2805 return false; | 2744 return false; |
| 2806 } | 2745 } |
| 2807 | 2746 |
| 2808 /** | 2747 /** |
| 2809 * This verifies that if the passed 'const' instance creation expression is be
ing invoked on the | 2748 * Verify that if the given 'const' instance creation [expression] is being |
| 2810 * resolved constructor. | 2749 * invoked on the resolved constructor. The [constructorName] is the |
| 2750 * constructor name, always non-`null`. The [typeName] is the name of the type |
| 2751 * defining the constructor, always non-`null`. |
| 2811 * | 2752 * |
| 2812 * This method assumes that the instance creation was tested to be 'const' bef
ore being called. | 2753 * This method assumes that the instance creation was tested to be 'const' |
| 2754 * before being called. |
| 2813 * | 2755 * |
| 2814 * @param node the instance creation expression to evaluate | |
| 2815 * @param constructorName the constructor name, always non-`null` | |
| 2816 * @param typeName the name of the type defining the constructor, always non-`
null` | |
| 2817 * @return `true` if and only if an error code is generated on the passed node | |
| 2818 * See [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR], and | 2756 * See [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR], and |
| 2819 * [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]. | 2757 * [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]. |
| 2820 */ | 2758 */ |
| 2821 bool _checkForConstWithUndefinedConstructor(InstanceCreationExpression node, | 2759 bool _checkForConstWithUndefinedConstructor(InstanceCreationExpression node, |
| 2822 ConstructorName constructorName, TypeName typeName) { | 2760 ConstructorName constructorName, TypeName typeName) { |
| 2823 // OK if resolved | 2761 // OK if resolved |
| 2824 if (node.staticElement != null) { | 2762 if (node.staticElement != null) { |
| 2825 return false; | 2763 return false; |
| 2826 } | 2764 } |
| 2827 DartType type = typeName.type; | 2765 DartType type = typeName.type; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2843 ]); | 2781 ]); |
| 2844 } else { | 2782 } else { |
| 2845 _errorReporter.reportErrorForNode( | 2783 _errorReporter.reportErrorForNode( |
| 2846 CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, | 2784 CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, |
| 2847 constructorName, [className]); | 2785 constructorName, [className]); |
| 2848 } | 2786 } |
| 2849 return true; | 2787 return true; |
| 2850 } | 2788 } |
| 2851 | 2789 |
| 2852 /** | 2790 /** |
| 2853 * This verifies that there are no default parameters in the passed function t
ype alias. | 2791 * Verify that there are no default parameters in the given function type |
| 2792 * [alias]. |
| 2854 * | 2793 * |
| 2855 * @param node the function type alias to evaluate | |
| 2856 * @return `true` if and only if an error code is generated on the passed node | |
| 2857 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]. | 2794 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]. |
| 2858 */ | 2795 */ |
| 2859 bool _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) { | 2796 bool _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) { |
| 2860 bool result = false; | 2797 bool result = false; |
| 2861 FormalParameterList formalParameterList = node.parameters; | 2798 FormalParameterList formalParameterList = node.parameters; |
| 2862 NodeList<FormalParameter> parameters = formalParameterList.parameters; | 2799 NodeList<FormalParameter> parameters = formalParameterList.parameters; |
| 2863 for (FormalParameter formalParameter in parameters) { | 2800 for (FormalParameter formalParameter in parameters) { |
| 2864 if (formalParameter is DefaultFormalParameter) { | 2801 if (formalParameter is DefaultFormalParameter) { |
| 2865 DefaultFormalParameter defaultFormalParameter = formalParameter; | 2802 DefaultFormalParameter defaultFormalParameter = formalParameter; |
| 2866 if (defaultFormalParameter.defaultValue != null) { | 2803 if (defaultFormalParameter.defaultValue != null) { |
| 2867 _errorReporter.reportErrorForNode( | 2804 _errorReporter.reportErrorForNode( |
| 2868 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, node); | 2805 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, node); |
| 2869 result = true; | 2806 result = true; |
| 2870 } | 2807 } |
| 2871 } | 2808 } |
| 2872 } | 2809 } |
| 2873 return result; | 2810 return result; |
| 2874 } | 2811 } |
| 2875 | 2812 |
| 2876 /** | 2813 /** |
| 2877 * This verifies that the given default formal parameter is not part of a func
tion typed | 2814 * Verify that the given default formal [parameter] is not part of a function |
| 2878 * parameter. | 2815 * typed parameter. |
| 2879 * | 2816 * |
| 2880 * @param node the default formal parameter to evaluate | |
| 2881 * @return `true` if and only if an error code is generated on the passed node | |
| 2882 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]. | 2817 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]. |
| 2883 */ | 2818 */ |
| 2884 bool _checkForDefaultValueInFunctionTypedParameter( | 2819 bool _checkForDefaultValueInFunctionTypedParameter( |
| 2885 DefaultFormalParameter node) { | 2820 DefaultFormalParameter node) { |
| 2886 // OK, not in a function typed parameter. | 2821 // OK, not in a function typed parameter. |
| 2887 if (!_isInFunctionTypedFormalParameter) { | 2822 if (!_isInFunctionTypedFormalParameter) { |
| 2888 return false; | 2823 return false; |
| 2889 } | 2824 } |
| 2890 // OK, no default value. | 2825 // OK, no default value. |
| 2891 if (node.defaultValue == null) { | 2826 if (node.defaultValue == null) { |
| 2892 return false; | 2827 return false; |
| 2893 } | 2828 } |
| 2894 // Report problem. | 2829 // Report problem. |
| 2895 _errorReporter.reportErrorForNode( | 2830 _errorReporter.reportErrorForNode( |
| 2896 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, node); | 2831 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, node); |
| 2897 return true; | 2832 return true; |
| 2898 } | 2833 } |
| 2899 | 2834 |
| 2900 /** | 2835 /** |
| 2901 * This verifies that any deferred imports in the given compilation unit have
a unique prefix. | 2836 * Verify that any deferred imports in the given compilation [unit] have a |
| 2837 * unique prefix. |
| 2902 * | 2838 * |
| 2903 * @param node the compilation unit containing the imports to be checked | |
| 2904 * @return `true` if an error was generated | |
| 2905 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. | 2839 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. |
| 2906 */ | 2840 */ |
| 2907 bool _checkForDeferredPrefixCollisions(CompilationUnit node) { | 2841 bool _checkForDeferredPrefixCollisions(CompilationUnit node) { |
| 2908 bool foundError = false; | 2842 bool foundError = false; |
| 2909 NodeList<Directive> directives = node.directives; | 2843 NodeList<Directive> directives = node.directives; |
| 2910 int count = directives.length; | 2844 int count = directives.length; |
| 2911 if (count > 0) { | 2845 if (count > 0) { |
| 2912 HashMap<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = | 2846 HashMap<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = |
| 2913 new HashMap<PrefixElement, List<ImportDirective>>(); | 2847 new HashMap<PrefixElement, List<ImportDirective>>(); |
| 2914 for (int i = 0; i < count; i++) { | 2848 for (int i = 0; i < count; i++) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2934 for (List<ImportDirective> imports in prefixToDirectivesMap.values) { | 2868 for (List<ImportDirective> imports in prefixToDirectivesMap.values) { |
| 2935 if (_hasDeferredPrefixCollision(imports)) { | 2869 if (_hasDeferredPrefixCollision(imports)) { |
| 2936 foundError = true; | 2870 foundError = true; |
| 2937 } | 2871 } |
| 2938 } | 2872 } |
| 2939 } | 2873 } |
| 2940 return foundError; | 2874 return foundError; |
| 2941 } | 2875 } |
| 2942 | 2876 |
| 2943 /** | 2877 /** |
| 2944 * This verifies that the enclosing class does not have an instance member wit
h the given name of | 2878 * Verify that the enclosing class does not have an instance member with the |
| 2945 * the static member. | 2879 * given name of the static member. |
| 2946 * | 2880 * |
| 2947 * @return `true` if and only if an error code is generated on the passed node | |
| 2948 * See [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]. | 2881 * See [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]. |
| 2949 */ | 2882 */ |
| 2950 bool _checkForDuplicateDefinitionInheritance() { | 2883 bool _checkForDuplicateDefinitionInheritance() { |
| 2951 if (_enclosingClass == null) { | 2884 if (_enclosingClass == null) { |
| 2952 return false; | 2885 return false; |
| 2953 } | 2886 } |
| 2954 bool hasProblem = false; | 2887 bool hasProblem = false; |
| 2955 for (ExecutableElement member in _enclosingClass.methods) { | 2888 for (ExecutableElement member in _enclosingClass.methods) { |
| 2956 if (member.isStatic && _checkForDuplicateDefinitionOfMember(member)) { | 2889 if (member.isStatic && _checkForDuplicateDefinitionOfMember(member)) { |
| 2957 hasProblem = true; | 2890 hasProblem = true; |
| 2958 } | 2891 } |
| 2959 } | 2892 } |
| 2960 for (ExecutableElement member in _enclosingClass.accessors) { | 2893 for (ExecutableElement member in _enclosingClass.accessors) { |
| 2961 if (member.isStatic && _checkForDuplicateDefinitionOfMember(member)) { | 2894 if (member.isStatic && _checkForDuplicateDefinitionOfMember(member)) { |
| 2962 hasProblem = true; | 2895 hasProblem = true; |
| 2963 } | 2896 } |
| 2964 } | 2897 } |
| 2965 return hasProblem; | 2898 return hasProblem; |
| 2966 } | 2899 } |
| 2967 | 2900 |
| 2968 /** | 2901 /** |
| 2969 * This verifies that the enclosing class does not have an instance member wit
h the given name of | 2902 * Verify that the enclosing class does not have an instance member with the |
| 2970 * the static member. | 2903 * given name of the [staticMember]. |
| 2971 * | 2904 * |
| 2972 * @param staticMember the static member to check conflict for | |
| 2973 * @return `true` if and only if an error code is generated on the passed node | |
| 2974 * See [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]. | 2905 * See [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]. |
| 2975 */ | 2906 */ |
| 2976 bool _checkForDuplicateDefinitionOfMember(ExecutableElement staticMember) { | 2907 bool _checkForDuplicateDefinitionOfMember(ExecutableElement staticMember) { |
| 2977 // prepare name | 2908 // prepare name |
| 2978 String name = staticMember.name; | 2909 String name = staticMember.name; |
| 2979 if (name == null) { | 2910 if (name == null) { |
| 2980 return false; | 2911 return false; |
| 2981 } | 2912 } |
| 2982 // try to find member | 2913 // try to find member |
| 2983 ExecutableElement inheritedMember = | 2914 ExecutableElement inheritedMember = |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2999 displayName = enclosingElement.getExtendedDisplayName(null); | 2930 displayName = enclosingElement.getExtendedDisplayName(null); |
| 3000 } | 2931 } |
| 3001 // report problem | 2932 // report problem |
| 3002 _errorReporter.reportErrorForOffset( | 2933 _errorReporter.reportErrorForOffset( |
| 3003 CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE, | 2934 CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE, |
| 3004 staticMember.nameOffset, name.length, [name, displayName]); | 2935 staticMember.nameOffset, name.length, [name, displayName]); |
| 3005 return true; | 2936 return true; |
| 3006 } | 2937 } |
| 3007 | 2938 |
| 3008 /** | 2939 /** |
| 3009 * This verifies if the passed list literal has type arguments then there is e
xactly one. | 2940 * Verify that if the given list [literal] has type arguments then there is |
| 2941 * exactly one. The [typeArguments] are the type arguments. |
| 3010 * | 2942 * |
| 3011 * @param node the list literal to evaluate | |
| 3012 * @param typeArguments the type arguments, always non-`null` | |
| 3013 * @return `true` if and only if an error code is generated on the passed node | |
| 3014 * See [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS]. | 2943 * See [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS]. |
| 3015 */ | 2944 */ |
| 3016 bool _checkForExpectedOneListTypeArgument( | 2945 bool _checkForExpectedOneListTypeArgument( |
| 3017 ListLiteral node, TypeArgumentList typeArguments) { | 2946 ListLiteral node, TypeArgumentList typeArguments) { |
| 3018 // check number of type arguments | 2947 // check number of type arguments |
| 3019 int num = typeArguments.arguments.length; | 2948 int num = typeArguments.arguments.length; |
| 3020 if (num == 1) { | 2949 if (num == 1) { |
| 3021 return false; | 2950 return false; |
| 3022 } | 2951 } |
| 3023 // report problem | 2952 // report problem |
| 3024 _errorReporter.reportErrorForNode( | 2953 _errorReporter.reportErrorForNode( |
| 3025 StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments, | 2954 StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments, |
| 3026 [num]); | 2955 [num]); |
| 3027 return true; | 2956 return true; |
| 3028 } | 2957 } |
| 3029 | 2958 |
| 3030 /** | 2959 /** |
| 3031 * This verifies the passed import has unique name among other exported librar
ies. | 2960 * Verify that the given export ([node]) has a unique name among other |
| 2961 * exported libraries. The [exportElement] is the [ExportElement] retrieved |
| 2962 * from the node, if the element in the node was `null`, then this method is |
| 2963 * not called. The [exportedLibrary] is the library element containing the |
| 2964 * exported element. |
| 3032 * | 2965 * |
| 3033 * @param node the export directive to evaluate | |
| 3034 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the | |
| 3035 * node was `null`, then this method is not called | |
| 3036 * @param exportedLibrary the library element containing the exported element | |
| 3037 * @return `true` if and only if an error code is generated on the passed node | |
| 3038 * See [CompileTimeErrorCode.EXPORT_DUPLICATED_LIBRARY_NAME]. | 2966 * See [CompileTimeErrorCode.EXPORT_DUPLICATED_LIBRARY_NAME]. |
| 3039 */ | 2967 */ |
| 3040 bool _checkForExportDuplicateLibraryName(ExportDirective node, | 2968 bool _checkForExportDuplicateLibraryName(ExportDirective node, |
| 3041 ExportElement exportElement, LibraryElement exportedLibrary) { | 2969 ExportElement exportElement, LibraryElement exportedLibrary) { |
| 3042 if (exportedLibrary == null) { | 2970 if (exportedLibrary == null) { |
| 3043 return false; | 2971 return false; |
| 3044 } | 2972 } |
| 3045 String name = exportedLibrary.name; | 2973 String name = exportedLibrary.name; |
| 3046 // check if there is other exported library with the same name | 2974 // check if there is other exported library with the same name |
| 3047 LibraryElement prevLibrary = _nameToExportElement[name]; | 2975 LibraryElement prevLibrary = _nameToExportElement[name]; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3064 return true; | 2992 return true; |
| 3065 } | 2993 } |
| 3066 } else { | 2994 } else { |
| 3067 _nameToExportElement[name] = exportedLibrary; | 2995 _nameToExportElement[name] = exportedLibrary; |
| 3068 } | 2996 } |
| 3069 // OK | 2997 // OK |
| 3070 return false; | 2998 return false; |
| 3071 } | 2999 } |
| 3072 | 3000 |
| 3073 /** | 3001 /** |
| 3074 * Check that if the visiting library is not system, then any passed library s
hould not be SDK | 3002 * Check that if the visiting library is not system, then any given library |
| 3075 * internal library. | 3003 * should not be SDK internal library. The [exportElement] is the |
| 3004 * [ExportElement] retrieved from the node, if the element in the node was |
| 3005 * `null`, then this method is not called. |
| 3076 * | 3006 * |
| 3077 * @param node the export directive to evaluate | |
| 3078 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the | |
| 3079 * node was `null`, then this method is not called | |
| 3080 * @return `true` if and only if an error code is generated on the passed node | |
| 3081 * See [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY]. | 3007 * See [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY]. |
| 3082 */ | 3008 */ |
| 3083 bool _checkForExportInternalLibrary( | 3009 bool _checkForExportInternalLibrary( |
| 3084 ExportDirective node, ExportElement exportElement) { | 3010 ExportDirective node, ExportElement exportElement) { |
| 3085 if (_isInSystemLibrary) { | 3011 if (_isInSystemLibrary) { |
| 3086 return false; | 3012 return false; |
| 3087 } | 3013 } |
| 3088 // should be private | 3014 // should be private |
| 3089 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; | 3015 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; |
| 3090 String uri = exportElement.uri; | 3016 String uri = exportElement.uri; |
| 3091 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); | 3017 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); |
| 3092 if (sdkLibrary == null) { | 3018 if (sdkLibrary == null) { |
| 3093 return false; | 3019 return false; |
| 3094 } | 3020 } |
| 3095 if (!sdkLibrary.isInternal) { | 3021 if (!sdkLibrary.isInternal) { |
| 3096 return false; | 3022 return false; |
| 3097 } | 3023 } |
| 3098 // report problem | 3024 // report problem |
| 3099 _errorReporter.reportErrorForNode( | 3025 _errorReporter.reportErrorForNode( |
| 3100 CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, node, [node.uri]); | 3026 CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, node, [node.uri]); |
| 3101 return true; | 3027 return true; |
| 3102 } | 3028 } |
| 3103 | 3029 |
| 3104 /** | 3030 /** |
| 3105 * This verifies that the passed extends clause does not extend a deferred cla
ss. | 3031 * Verify that the given extends [clause] does not extend a deferred class. |
| 3106 * | 3032 * |
| 3107 * @param node the extends clause to test | |
| 3108 * @return `true` if and only if an error code is generated on the passed node | |
| 3109 * See [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS]. | 3033 * See [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS]. |
| 3110 */ | 3034 */ |
| 3111 bool _checkForExtendsDeferredClass(ExtendsClause node) { | 3035 bool _checkForExtendsDeferredClass(ExtendsClause node) { |
| 3112 if (node == null) { | 3036 if (node == null) { |
| 3113 return false; | 3037 return false; |
| 3114 } | 3038 } |
| 3115 return _checkForExtendsOrImplementsDeferredClass( | 3039 return _checkForExtendsOrImplementsDeferredClass( |
| 3116 node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); | 3040 node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); |
| 3117 } | 3041 } |
| 3118 | 3042 |
| 3119 /** | 3043 /** |
| 3120 * This verifies that the passed type alias does not extend a deferred class. | 3044 * Verify that the given type [alias] does not extend a deferred class. |
| 3121 * | 3045 * |
| 3122 * @param node the extends clause to test | |
| 3123 * @return `true` if and only if an error code is generated on the passed node | |
| 3124 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. | 3046 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. |
| 3125 */ | 3047 */ |
| 3126 bool _checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias node) { | 3048 bool _checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias node) { |
| 3127 if (node == null) { | 3049 if (node == null) { |
| 3128 return false; | 3050 return false; |
| 3129 } | 3051 } |
| 3130 return _checkForExtendsOrImplementsDeferredClass( | 3052 return _checkForExtendsOrImplementsDeferredClass( |
| 3131 node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); | 3053 node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); |
| 3132 } | 3054 } |
| 3133 | 3055 |
| 3134 /** | 3056 /** |
| 3135 * This verifies that the passed extends clause does not extend classes such a
s num or String. | 3057 * Verify that the given extends [clause] does not extend classes such as |
| 3058 * 'num' or 'String'. |
| 3136 * | 3059 * |
| 3137 * @param node the extends clause to test | |
| 3138 * @return `true` if and only if an error code is generated on the passed node | |
| 3139 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. | 3060 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. |
| 3140 */ | 3061 */ |
| 3141 bool _checkForExtendsDisallowedClass(ExtendsClause node) { | 3062 bool _checkForExtendsDisallowedClass(ExtendsClause node) { |
| 3142 if (node == null) { | 3063 if (node == null) { |
| 3143 return false; | 3064 return false; |
| 3144 } | 3065 } |
| 3145 return _checkForExtendsOrImplementsDisallowedClass( | 3066 return _checkForExtendsOrImplementsDisallowedClass( |
| 3146 node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); | 3067 node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); |
| 3147 } | 3068 } |
| 3148 | 3069 |
| 3149 /** | 3070 /** |
| 3150 * This verifies that the passed type alias does not extend classes such as nu
m or String. | 3071 * Verify that the given type [alias] does not extend classes such as 'num' or |
| 3072 * 'String'. |
| 3151 * | 3073 * |
| 3152 * @param node the extends clause to test | |
| 3153 * @return `true` if and only if an error code is generated on the passed node | |
| 3154 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. | 3074 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. |
| 3155 */ | 3075 */ |
| 3156 bool _checkForExtendsDisallowedClassInTypeAlias(ClassTypeAlias node) { | 3076 bool _checkForExtendsDisallowedClassInTypeAlias(ClassTypeAlias node) { |
| 3157 if (node == null) { | 3077 if (node == null) { |
| 3158 return false; | 3078 return false; |
| 3159 } | 3079 } |
| 3160 return _checkForExtendsOrImplementsDisallowedClass( | 3080 return _checkForExtendsOrImplementsDisallowedClass( |
| 3161 node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); | 3081 node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); |
| 3162 } | 3082 } |
| 3163 | 3083 |
| 3164 /** | 3084 /** |
| 3165 * This verifies that the passed type name does not extend, implement or mixin
classes that are | 3085 * Verify that the given [typeName] does not extend, implement or mixin |
| 3166 * deferred. | 3086 * classes that are deferred. |
| 3167 * | 3087 * |
| 3168 * @param node the type name to test | |
| 3169 * @return `true` if and only if an error code is generated on the passed node | |
| 3170 * See [_checkForExtendsDeferredClass], | 3088 * See [_checkForExtendsDeferredClass], |
| 3171 * [_checkForExtendsDeferredClassInTypeAlias], | 3089 * [_checkForExtendsDeferredClassInTypeAlias], |
| 3172 * [_checkForImplementsDeferredClass], | 3090 * [_checkForImplementsDeferredClass], |
| 3173 * [_checkForAllMixinErrorCodes], | 3091 * [_checkForAllMixinErrorCodes], |
| 3174 * [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS], | 3092 * [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS], |
| 3175 * [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS], and | 3093 * [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS], and |
| 3176 * [CompileTimeErrorCode.MIXIN_DEFERRED_CLASS]. | 3094 * [CompileTimeErrorCode.MIXIN_DEFERRED_CLASS]. |
| 3177 */ | 3095 */ |
| 3178 bool _checkForExtendsOrImplementsDeferredClass( | 3096 bool _checkForExtendsOrImplementsDeferredClass( |
| 3179 TypeName typeName, ErrorCode errorCode) { | 3097 TypeName typeName, ErrorCode errorCode) { |
| 3180 if (typeName.isSynthetic) { | 3098 if (typeName.isSynthetic) { |
| 3181 return false; | 3099 return false; |
| 3182 } | 3100 } |
| 3183 if (typeName.isDeferred) { | 3101 if (typeName.isDeferred) { |
| 3184 _errorReporter.reportErrorForNode( | 3102 _errorReporter.reportErrorForNode( |
| 3185 errorCode, typeName, [typeName.name.name]); | 3103 errorCode, typeName, [typeName.name.name]); |
| 3186 return true; | 3104 return true; |
| 3187 } | 3105 } |
| 3188 return false; | 3106 return false; |
| 3189 } | 3107 } |
| 3190 | 3108 |
| 3191 /** | 3109 /** |
| 3192 * This verifies that the passed type name does not extend, implement or mixin
classes such as | 3110 * Verify that the given [typeName] does not extend, implement or mixin |
| 3193 * 'num' or 'String'. | 3111 * classes such as 'num' or 'String'. |
| 3194 * | 3112 * |
| 3195 * @param node the type name to test | |
| 3196 * @return `true` if and only if an error code is generated on the passed node | |
| 3197 * See [_checkForExtendsDisallowedClass], | 3113 * See [_checkForExtendsDisallowedClass], |
| 3198 * [_checkForExtendsDisallowedClassInTypeAlias], | 3114 * [_checkForExtendsDisallowedClassInTypeAlias], |
| 3199 * [_checkForImplementsDisallowedClass], | 3115 * [_checkForImplementsDisallowedClass], |
| 3200 * [_checkForAllMixinErrorCodes], | 3116 * [_checkForAllMixinErrorCodes], |
| 3201 * [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS], | 3117 * [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS], |
| 3202 * [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS], and | 3118 * [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS], and |
| 3203 * [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]. | 3119 * [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]. |
| 3204 */ | 3120 */ |
| 3205 bool _checkForExtendsOrImplementsDisallowedClass( | 3121 bool _checkForExtendsOrImplementsDisallowedClass( |
| 3206 TypeName typeName, ErrorCode errorCode) { | 3122 TypeName typeName, ErrorCode errorCode) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3233 // otherwise, report the error | 3149 // otherwise, report the error |
| 3234 _errorReporter.reportErrorForNode( | 3150 _errorReporter.reportErrorForNode( |
| 3235 errorCode, typeName, [disallowedType.displayName]); | 3151 errorCode, typeName, [disallowedType.displayName]); |
| 3236 return true; | 3152 return true; |
| 3237 } | 3153 } |
| 3238 } | 3154 } |
| 3239 return false; | 3155 return false; |
| 3240 } | 3156 } |
| 3241 | 3157 |
| 3242 /** | 3158 /** |
| 3243 * This verifies that the passed constructor field initializer has compatible
field and | 3159 * Verify that the given constructor field [initializer] has compatible field |
| 3244 * initializer expression types. | 3160 * and initializer expression types. The [staticElement] is the static element |
| 3161 * from the name in the [ConstructorFieldInitializer]. |
| 3245 * | 3162 * |
| 3246 * @param node the constructor field initializer to test | |
| 3247 * @param staticElement the static element from the name in the | |
| 3248 * [ConstructorFieldInitializer] | |
| 3249 * @return `true` if and only if an error code is generated on the passed node | |
| 3250 * See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and | 3163 * See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and |
| 3251 * [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE]. | 3164 * [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE]. |
| 3252 */ | 3165 */ |
| 3253 bool _checkForFieldInitializerNotAssignable( | 3166 bool _checkForFieldInitializerNotAssignable( |
| 3254 ConstructorFieldInitializer node, Element staticElement) { | 3167 ConstructorFieldInitializer node, Element staticElement) { |
| 3255 // prepare field element | 3168 // prepare field element |
| 3256 if (staticElement is! FieldElement) { | 3169 if (staticElement is! FieldElement) { |
| 3257 return false; | 3170 return false; |
| 3258 } | 3171 } |
| 3259 FieldElement fieldElement = staticElement as FieldElement; | 3172 FieldElement fieldElement = staticElement as FieldElement; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3304 // errorReporter.reportTypeErrorForNode( | 3217 // errorReporter.reportTypeErrorForNode( |
| 3305 // StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, | 3218 // StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, |
| 3306 // expression, | 3219 // expression, |
| 3307 // propagatedType == null ? staticType : propagatedType, | 3220 // propagatedType == null ? staticType : propagatedType, |
| 3308 // fieldType); | 3221 // fieldType); |
| 3309 // } | 3222 // } |
| 3310 // return true; | 3223 // return true; |
| 3311 } | 3224 } |
| 3312 | 3225 |
| 3313 /** | 3226 /** |
| 3314 * This verifies that the passed field formal parameter is in a constructor de
claration. | 3227 * Verify that the given field formal [parameter] is in a constructor |
| 3228 * declaration. |
| 3315 * | 3229 * |
| 3316 * @param node the field formal parameter to test | |
| 3317 * @return `true` if and only if an error code is generated on the passed node | |
| 3318 * See [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]. | 3230 * See [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]. |
| 3319 */ | 3231 */ |
| 3320 bool _checkForFieldInitializingFormalRedirectingConstructor( | 3232 bool _checkForFieldInitializingFormalRedirectingConstructor( |
| 3321 FieldFormalParameter node) { | 3233 FieldFormalParameter node) { |
| 3322 ConstructorDeclaration constructor = | 3234 ConstructorDeclaration constructor = |
| 3323 node.getAncestor((node) => node is ConstructorDeclaration); | 3235 node.getAncestor((node) => node is ConstructorDeclaration); |
| 3324 if (constructor == null) { | 3236 if (constructor == null) { |
| 3325 _errorReporter.reportErrorForNode( | 3237 _errorReporter.reportErrorForNode( |
| 3326 CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, node); | 3238 CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, node); |
| 3327 return true; | 3239 return true; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3339 CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, | 3251 CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, |
| 3340 node); | 3252 node); |
| 3341 return true; | 3253 return true; |
| 3342 } | 3254 } |
| 3343 } | 3255 } |
| 3344 // OK | 3256 // OK |
| 3345 return false; | 3257 return false; |
| 3346 } | 3258 } |
| 3347 | 3259 |
| 3348 /** | 3260 /** |
| 3349 * This verifies that the passed variable declaration list has only initialize
d variables if the | 3261 * Verify that the given variable declaration [list] has only initialized |
| 3350 * list is final or const. This method is called by | 3262 * variables if the list is final or const. |
| 3351 * [checkForFinalNotInitializedInClass], | |
| 3352 * [visitTopLevelVariableDeclaration] and | |
| 3353 * [visitVariableDeclarationStatement]. | |
| 3354 * | 3263 * |
| 3355 * @param node the class declaration to test | |
| 3356 * @return `true` if and only if an error code is generated on the passed node | |
| 3357 * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and | 3264 * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and |
| 3358 * [StaticWarningCode.FINAL_NOT_INITIALIZED]. | 3265 * [StaticWarningCode.FINAL_NOT_INITIALIZED]. |
| 3359 */ | 3266 */ |
| 3360 bool _checkForFinalNotInitialized(VariableDeclarationList node) { | 3267 bool _checkForFinalNotInitialized(VariableDeclarationList node) { |
| 3361 if (_isInNativeClass) { | 3268 if (_isInNativeClass) { |
| 3362 return false; | 3269 return false; |
| 3363 } | 3270 } |
| 3364 bool foundError = false; | 3271 bool foundError = false; |
| 3365 if (!node.isSynthetic) { | 3272 if (!node.isSynthetic) { |
| 3366 NodeList<VariableDeclaration> variables = node.variables; | 3273 NodeList<VariableDeclaration> variables = node.variables; |
| 3367 for (VariableDeclaration variable in variables) { | 3274 for (VariableDeclaration variable in variables) { |
| 3368 if (variable.initializer == null) { | 3275 if (variable.initializer == null) { |
| 3369 if (node.isConst) { | 3276 if (node.isConst) { |
| 3370 _errorReporter.reportErrorForNode( | 3277 _errorReporter.reportErrorForNode( |
| 3371 CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, | 3278 CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, |
| 3372 [variable.name.name]); | 3279 [variable.name.name]); |
| 3373 } else if (node.isFinal) { | 3280 } else if (node.isFinal) { |
| 3374 _errorReporter.reportErrorForNode( | 3281 _errorReporter.reportErrorForNode( |
| 3375 StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, | 3282 StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, |
| 3376 [variable.name.name]); | 3283 [variable.name.name]); |
| 3377 } | 3284 } |
| 3378 foundError = true; | 3285 foundError = true; |
| 3379 } | 3286 } |
| 3380 } | 3287 } |
| 3381 } | 3288 } |
| 3382 return foundError; | 3289 return foundError; |
| 3383 } | 3290 } |
| 3384 | 3291 |
| 3385 /** | 3292 /** |
| 3386 * This verifies that final fields that are declared, without any constructors
in the enclosing | 3293 * Verify that final fields in the given clas [declaration] that are declared, |
| 3387 * class, are initialized. Cases in which there is at least one constructor ar
e handled at the end | 3294 * without any constructors in the enclosing class, are initialized. Cases in |
| 3388 * of [checkForAllFinalInitializedErrorCodes]. | 3295 * which there is at least one constructor are handled at the end of |
| 3296 * [_checkForAllFinalInitializedErrorCodes]. |
| 3389 * | 3297 * |
| 3390 * @param node the class declaration to test | |
| 3391 * @return `true` if and only if an error code is generated on the passed node | |
| 3392 * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and | 3298 * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and |
| 3393 * [StaticWarningCode.FINAL_NOT_INITIALIZED]. | 3299 * [StaticWarningCode.FINAL_NOT_INITIALIZED]. |
| 3394 */ | 3300 */ |
| 3395 bool _checkForFinalNotInitializedInClass(ClassDeclaration node) { | 3301 bool _checkForFinalNotInitializedInClass(ClassDeclaration node) { |
| 3396 NodeList<ClassMember> classMembers = node.members; | 3302 NodeList<ClassMember> classMembers = node.members; |
| 3397 for (ClassMember classMember in classMembers) { | 3303 for (ClassMember classMember in classMembers) { |
| 3398 if (classMember is ConstructorDeclaration) { | 3304 if (classMember is ConstructorDeclaration) { |
| 3399 return false; | 3305 return false; |
| 3400 } | 3306 } |
| 3401 } | 3307 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3437 } else if (_enclosingFunction.isGenerator) { | 3343 } else if (_enclosingFunction.isGenerator) { |
| 3438 if (!_enclosingFunction.returnType | 3344 if (!_enclosingFunction.returnType |
| 3439 .isAssignableTo(_typeProvider.iterableDynamicType)) { | 3345 .isAssignableTo(_typeProvider.iterableDynamicType)) { |
| 3440 _errorReporter.reportErrorForNode( | 3346 _errorReporter.reportErrorForNode( |
| 3441 StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, node); | 3347 StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, node); |
| 3442 } | 3348 } |
| 3443 } | 3349 } |
| 3444 } | 3350 } |
| 3445 | 3351 |
| 3446 /** | 3352 /** |
| 3447 * This verifies that the passed implements clause does not implement classes
that are deferred. | 3353 * Verify that the given implements [clause] does not implement classes that |
| 3354 * are deferred. |
| 3448 * | 3355 * |
| 3449 * @param node the implements clause to test | |
| 3450 * @return `true` if and only if an error code is generated on the passed node | |
| 3451 * See [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS]. | 3356 * See [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS]. |
| 3452 */ | 3357 */ |
| 3453 bool _checkForImplementsDeferredClass(ImplementsClause node) { | 3358 bool _checkForImplementsDeferredClass(ImplementsClause node) { |
| 3454 if (node == null) { | 3359 if (node == null) { |
| 3455 return false; | 3360 return false; |
| 3456 } | 3361 } |
| 3457 bool foundError = false; | 3362 bool foundError = false; |
| 3458 for (TypeName type in node.interfaces) { | 3363 for (TypeName type in node.interfaces) { |
| 3459 if (_checkForExtendsOrImplementsDeferredClass( | 3364 if (_checkForExtendsOrImplementsDeferredClass( |
| 3460 type, CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS)) { | 3365 type, CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS)) { |
| 3461 foundError = true; | 3366 foundError = true; |
| 3462 } | 3367 } |
| 3463 } | 3368 } |
| 3464 return foundError; | 3369 return foundError; |
| 3465 } | 3370 } |
| 3466 | 3371 |
| 3467 /** | 3372 /** |
| 3468 * This verifies that the passed implements clause does not implement classes
such as 'num' or | 3373 * Verify that the given implements [clause] does not implement classes such |
| 3469 * 'String'. | 3374 * as 'num' or 'String'. |
| 3470 * | 3375 * |
| 3471 * @param node the implements clause to test | |
| 3472 * @return `true` if and only if an error code is generated on the passed node | |
| 3473 * See [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]. | 3376 * See [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]. |
| 3474 */ | 3377 */ |
| 3475 bool _checkForImplementsDisallowedClass(ImplementsClause node) { | 3378 bool _checkForImplementsDisallowedClass(ImplementsClause node) { |
| 3476 if (node == null) { | 3379 if (node == null) { |
| 3477 return false; | 3380 return false; |
| 3478 } | 3381 } |
| 3479 bool foundError = false; | 3382 bool foundError = false; |
| 3480 for (TypeName type in node.interfaces) { | 3383 for (TypeName type in node.interfaces) { |
| 3481 if (_checkForExtendsOrImplementsDisallowedClass( | 3384 if (_checkForExtendsOrImplementsDisallowedClass( |
| 3482 type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) { | 3385 type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) { |
| 3483 foundError = true; | 3386 foundError = true; |
| 3484 } | 3387 } |
| 3485 } | 3388 } |
| 3486 return foundError; | 3389 return foundError; |
| 3487 } | 3390 } |
| 3488 | 3391 |
| 3489 /** | 3392 /** |
| 3490 * This verifies that if the passed identifier is part of constructor initiali
zer, then it does | 3393 * Verify that if the given [identifier] is part of a constructor initializer, |
| 3491 * not reference implicitly 'this' expression. | 3394 * then it does not implicitly reference 'this' expression. |
| 3492 * | 3395 * |
| 3493 * @param node the simple identifier to test | |
| 3494 * @return `true` if and only if an error code is generated on the passed node | |
| 3495 * See [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER], and | 3396 * See [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER], and |
| 3496 * [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]. | 3397 * [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]. |
| 3497 * TODO(scheglov) rename thid method | 3398 * TODO(scheglov) rename thid method |
| 3498 */ | 3399 */ |
| 3499 bool _checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) { | 3400 bool _checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) { |
| 3500 if (!_isInConstructorInitializer && | 3401 if (!_isInConstructorInitializer && |
| 3501 !_isInStaticMethod && | 3402 !_isInStaticMethod && |
| 3502 !_isInFactory && | 3403 !_isInFactory && |
| 3503 !_isInInstanceVariableInitializer && | 3404 !_isInInstanceVariableInitializer && |
| 3504 !_isInStaticVariableDeclaration) { | 3405 !_isInStaticVariableDeclaration) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3553 _errorReporter.reportErrorForNode( | 3454 _errorReporter.reportErrorForNode( |
| 3554 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, node); | 3455 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, node); |
| 3555 } else { | 3456 } else { |
| 3556 _errorReporter.reportErrorForNode( | 3457 _errorReporter.reportErrorForNode( |
| 3557 CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, node); | 3458 CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, node); |
| 3558 } | 3459 } |
| 3559 return true; | 3460 return true; |
| 3560 } | 3461 } |
| 3561 | 3462 |
| 3562 /** | 3463 /** |
| 3563 * This verifies the passed import has unique name among other imported librar
ies. | 3464 * Verify that the given import [directive] has a unique name among other |
| 3465 * imported libraries. The [importElement] is the [ImportElement] retrieved |
| 3466 * from the node, if the element in the node was `null`, then this method is |
| 3467 * not called. |
| 3564 * | 3468 * |
| 3565 * @param node the import directive to evaluate | |
| 3566 * @param importElement the [ImportElement] retrieved from the node, if the el
ement in the | |
| 3567 * node was `null`, then this method is not called | |
| 3568 * @return `true` if and only if an error code is generated on the passed node | |
| 3569 * See [CompileTimeErrorCode.IMPORT_DUPLICATED_LIBRARY_NAME]. | 3469 * See [CompileTimeErrorCode.IMPORT_DUPLICATED_LIBRARY_NAME]. |
| 3570 */ | 3470 */ |
| 3571 bool _checkForImportDuplicateLibraryName( | 3471 bool _checkForImportDuplicateLibraryName( |
| 3572 ImportDirective node, ImportElement importElement) { | 3472 ImportDirective node, ImportElement importElement) { |
| 3573 // prepare imported library | 3473 // prepare imported library |
| 3574 LibraryElement nodeLibrary = importElement.importedLibrary; | 3474 LibraryElement nodeLibrary = importElement.importedLibrary; |
| 3575 if (nodeLibrary == null) { | 3475 if (nodeLibrary == null) { |
| 3576 return false; | 3476 return false; |
| 3577 } | 3477 } |
| 3578 String name = nodeLibrary.name; | 3478 String name = nodeLibrary.name; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3597 return true; | 3497 return true; |
| 3598 } | 3498 } |
| 3599 } else { | 3499 } else { |
| 3600 _nameToImportElement[name] = nodeLibrary; | 3500 _nameToImportElement[name] = nodeLibrary; |
| 3601 } | 3501 } |
| 3602 // OK | 3502 // OK |
| 3603 return false; | 3503 return false; |
| 3604 } | 3504 } |
| 3605 | 3505 |
| 3606 /** | 3506 /** |
| 3607 * Check that if the visiting library is not system, then any passed library s
hould not be SDK | 3507 * Check that if the visiting library is not system, then any given library |
| 3608 * internal library. | 3508 * should not be SDK internal library. The [importElement] is the |
| 3509 * [ImportElement] retrieved from the node, if the element in the node was |
| 3510 * `null`, then this method is not called |
| 3609 * | 3511 * |
| 3610 * @param node the import directive to evaluate | |
| 3611 * @param importElement the [ImportElement] retrieved from the node, if the el
ement in the | |
| 3612 * node was `null`, then this method is not called | |
| 3613 * @return `true` if and only if an error code is generated on the passed node | |
| 3614 * See [CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY]. | 3512 * See [CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY]. |
| 3615 */ | 3513 */ |
| 3616 bool _checkForImportInternalLibrary( | 3514 bool _checkForImportInternalLibrary( |
| 3617 ImportDirective node, ImportElement importElement) { | 3515 ImportDirective node, ImportElement importElement) { |
| 3618 if (_isInSystemLibrary) { | 3516 if (_isInSystemLibrary) { |
| 3619 return false; | 3517 return false; |
| 3620 } | 3518 } |
| 3621 // should be private | 3519 // should be private |
| 3622 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; | 3520 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; |
| 3623 String uri = importElement.uri; | 3521 String uri = importElement.uri; |
| 3624 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); | 3522 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); |
| 3625 if (sdkLibrary == null) { | 3523 if (sdkLibrary == null) { |
| 3626 return false; | 3524 return false; |
| 3627 } | 3525 } |
| 3628 if (!sdkLibrary.isInternal) { | 3526 if (!sdkLibrary.isInternal) { |
| 3629 return false; | 3527 return false; |
| 3630 } | 3528 } |
| 3631 // report problem | 3529 // report problem |
| 3632 _errorReporter.reportErrorForNode( | 3530 _errorReporter.reportErrorForNode( |
| 3633 CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, node, [node.uri]); | 3531 CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, node, [node.uri]); |
| 3634 return true; | 3532 return true; |
| 3635 } | 3533 } |
| 3636 | 3534 |
| 3637 /** | 3535 /** |
| 3638 * For each class declaration, this method is called which verifies that all i
nherited members are | 3536 * For each class declaration, this method is called which verifies that all |
| 3639 * inherited consistently. | 3537 * inherited members are inherited consistently. |
| 3640 * | 3538 * |
| 3641 * @return `true` if and only if an error code is generated on the passed node | |
| 3642 * See [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]. | 3539 * See [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]. |
| 3643 */ | 3540 */ |
| 3644 bool _checkForInconsistentMethodInheritance() { | 3541 bool _checkForInconsistentMethodInheritance() { |
| 3645 // Ensure that the inheritance manager has a chance to generate all errors | 3542 // Ensure that the inheritance manager has a chance to generate all errors |
| 3646 // we may care about, note that we ensure that the interfaces data since | 3543 // we may care about, note that we ensure that the interfaces data since |
| 3647 // there are no errors. | 3544 // there are no errors. |
| 3648 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass); | 3545 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass); |
| 3649 HashSet<AnalysisError> errors = | 3546 HashSet<AnalysisError> errors = |
| 3650 _inheritanceManager.getErrors(_enclosingClass); | 3547 _inheritanceManager.getErrors(_enclosingClass); |
| 3651 if (errors == null || errors.isEmpty) { | 3548 if (errors == null || errors.isEmpty) { |
| 3652 return false; | 3549 return false; |
| 3653 } | 3550 } |
| 3654 for (AnalysisError error in errors) { | 3551 for (AnalysisError error in errors) { |
| 3655 _errorReporter.reportError(error); | 3552 _errorReporter.reportError(error); |
| 3656 } | 3553 } |
| 3657 return true; | 3554 return true; |
| 3658 } | 3555 } |
| 3659 | 3556 |
| 3660 /** | 3557 /** |
| 3661 * This checks the given "typeReference" is not a type reference and that then
the "name" is | 3558 * Check that the given [typeReference] is not a type reference and that then |
| 3662 * reference to an instance member. | 3559 * the [name] is reference to an instance member. |
| 3663 * | 3560 * |
| 3664 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, | |
| 3665 * or `null`, aka, the class element of 'C' in 'C.x', see | |
| 3666 * [getTypeReference] | |
| 3667 * @param name the accessed name to evaluate | |
| 3668 * @return `true` if and only if an error code is generated on the passed node | |
| 3669 * See [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]. | 3561 * See [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]. |
| 3670 */ | 3562 */ |
| 3671 bool _checkForInstanceAccessToStaticMember( | 3563 bool _checkForInstanceAccessToStaticMember( |
| 3672 ClassElement typeReference, SimpleIdentifier name) { | 3564 ClassElement typeReference, SimpleIdentifier name) { |
| 3673 // OK, in comment | 3565 // OK, in comment |
| 3674 if (_isInComment) { | 3566 if (_isInComment) { |
| 3675 return false; | 3567 return false; |
| 3676 } | 3568 } |
| 3677 // OK, target is a type | 3569 // OK, target is a type |
| 3678 if (typeReference != null) { | 3570 if (typeReference != null) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3693 return false; | 3585 return false; |
| 3694 } | 3586 } |
| 3695 // report problem | 3587 // report problem |
| 3696 _errorReporter.reportErrorForNode( | 3588 _errorReporter.reportErrorForNode( |
| 3697 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name, | 3589 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name, |
| 3698 [name.name]); | 3590 [name.name]); |
| 3699 return true; | 3591 return true; |
| 3700 } | 3592 } |
| 3701 | 3593 |
| 3702 /** | 3594 /** |
| 3703 * This checks whether the given [executableElement] collides with the name of
a static | 3595 * Check whether the given [executableElement] collides with the name of a |
| 3704 * method in one of its superclasses, and reports the appropriate warning if i
t does. | 3596 * static method in one of its superclasses, and reports the appropriate |
| 3597 * warning if it does. The [errorNameTarget] is the node to report problems |
| 3598 * on. |
| 3705 * | 3599 * |
| 3706 * @param executableElement the method to check. | |
| 3707 * @param errorNameTarget the node to report problems on. | |
| 3708 * @return `true` if and only if a warning was generated. | |
| 3709 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST
ATIC]. | 3600 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST
ATIC]. |
| 3710 */ | 3601 */ |
| 3711 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic( | 3602 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic( |
| 3712 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) { | 3603 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) { |
| 3713 String executableElementName = executableElement.name; | 3604 String executableElementName = executableElement.name; |
| 3714 if (executableElement is! PropertyAccessorElement && | 3605 if (executableElement is! PropertyAccessorElement && |
| 3715 !executableElement.isOperator) { | 3606 !executableElement.isOperator) { |
| 3716 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>(); | 3607 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>(); |
| 3717 InterfaceType superclassType = _enclosingClass.supertype; | 3608 InterfaceType superclassType = _enclosingClass.supertype; |
| 3718 ClassElement superclassElement = | 3609 ClassElement superclassElement = |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3768 } | 3659 } |
| 3769 superclassType = superclassElement.supertype; | 3660 superclassType = superclassElement.supertype; |
| 3770 superclassElement = | 3661 superclassElement = |
| 3771 superclassType == null ? null : superclassType.element; | 3662 superclassType == null ? null : superclassType.element; |
| 3772 } | 3663 } |
| 3773 } | 3664 } |
| 3774 return false; | 3665 return false; |
| 3775 } | 3666 } |
| 3776 | 3667 |
| 3777 /** | 3668 /** |
| 3778 * This verifies that an 'int' can be assigned to the parameter corresponding
to the given | 3669 * Verify that an 'int' can be assigned to the parameter corresponding to the |
| 3779 * expression. This is used for prefix and postfix expressions where the argum
ent value is | 3670 * given [expression]. This is used for prefix and postfix expressions where |
| 3780 * implicit. | 3671 * the argument value is implicit. |
| 3781 * | 3672 * |
| 3782 * @param argument the expression to which the operator is being applied | |
| 3783 * @return `true` if and only if an error code is generated on the passed node | |
| 3784 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. | 3673 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. |
| 3785 */ | 3674 */ |
| 3786 bool _checkForIntNotAssignable(Expression argument) { | 3675 bool _checkForIntNotAssignable(Expression argument) { |
| 3787 if (argument == null) { | 3676 if (argument == null) { |
| 3788 return false; | 3677 return false; |
| 3789 } | 3678 } |
| 3790 ParameterElement staticParameterElement = argument.staticParameterElement; | 3679 ParameterElement staticParameterElement = argument.staticParameterElement; |
| 3791 DartType staticParameterType = | 3680 DartType staticParameterType = |
| 3792 staticParameterElement == null ? null : staticParameterElement.type; | 3681 staticParameterElement == null ? null : staticParameterElement.type; |
| 3793 return _checkForArgumentTypeNotAssignable(argument, staticParameterType, | 3682 return _checkForArgumentTypeNotAssignable(argument, staticParameterType, |
| 3794 _intType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); | 3683 _intType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); |
| 3795 } | 3684 } |
| 3796 | 3685 |
| 3797 /** | 3686 /** |
| 3798 * This verifies that the passed [Annotation] isn't defined in a deferred libr
ary. | 3687 * Verify that the given [annotation] isn't defined in a deferred library. |
| 3799 * | 3688 * |
| 3800 * @param node the [Annotation] | |
| 3801 * @return `true` if and only if an error code is generated on the passed node | |
| 3802 * See [CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY]. | 3689 * See [CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY]. |
| 3803 */ | 3690 */ |
| 3804 bool _checkForInvalidAnnotationFromDeferredLibrary(Annotation node) { | 3691 bool _checkForInvalidAnnotationFromDeferredLibrary(Annotation node) { |
| 3805 Identifier nameIdentifier = node.name; | 3692 Identifier nameIdentifier = node.name; |
| 3806 if (nameIdentifier is PrefixedIdentifier) { | 3693 if (nameIdentifier is PrefixedIdentifier) { |
| 3807 if (nameIdentifier.isDeferred) { | 3694 if (nameIdentifier.isDeferred) { |
| 3808 _errorReporter.reportErrorForNode( | 3695 _errorReporter.reportErrorForNode( |
| 3809 CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY, | 3696 CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY, |
| 3810 node.name); | 3697 node.name); |
| 3811 return true; | 3698 return true; |
| 3812 } | 3699 } |
| 3813 } | 3700 } |
| 3814 return false; | 3701 return false; |
| 3815 } | 3702 } |
| 3816 | 3703 |
| 3817 /** | 3704 /** |
| 3818 * This verifies that the passed left hand side and right hand side represent
a valid assignment. | 3705 * Verify that the given left hand side ([lhs]) and right hand side ([rhs]) |
| 3706 * represent a valid assignment. |
| 3819 * | 3707 * |
| 3820 * @param lhs the left hand side expression | |
| 3821 * @param rhs the right hand side expression | |
| 3822 * @return `true` if and only if an error code is generated on the passed node | |
| 3823 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT]. | 3708 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT]. |
| 3824 */ | 3709 */ |
| 3825 bool _checkForInvalidAssignment(Expression lhs, Expression rhs) { | 3710 bool _checkForInvalidAssignment(Expression lhs, Expression rhs) { |
| 3826 if (lhs == null || rhs == null) { | 3711 if (lhs == null || rhs == null) { |
| 3827 return false; | 3712 return false; |
| 3828 } | 3713 } |
| 3829 VariableElement leftVariableElement = getVariableElement(lhs); | 3714 VariableElement leftVariableElement = getVariableElement(lhs); |
| 3830 DartType leftType = (leftVariableElement == null) | 3715 DartType leftType = (leftVariableElement == null) |
| 3831 ? getStaticType(lhs) | 3716 ? getStaticType(lhs) |
| 3832 : leftVariableElement.type; | 3717 : leftVariableElement.type; |
| 3833 DartType staticRightType = getStaticType(rhs); | 3718 DartType staticRightType = getStaticType(rhs); |
| 3834 if (!staticRightType.isAssignableTo(leftType)) { | 3719 if (!staticRightType.isAssignableTo(leftType)) { |
| 3835 _errorReporter.reportTypeErrorForNode( | 3720 _errorReporter.reportTypeErrorForNode( |
| 3836 StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [ | 3721 StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [ |
| 3837 staticRightType, | 3722 staticRightType, |
| 3838 leftType | 3723 leftType |
| 3839 ]); | 3724 ]); |
| 3840 return true; | 3725 return true; |
| 3841 } | 3726 } |
| 3842 return false; | 3727 return false; |
| 3843 } | 3728 } |
| 3844 | 3729 |
| 3845 /** | 3730 /** |
| 3846 * Given an assignment using a compound assignment operator, this verifies tha
t the given | 3731 * Given an [assignment] using a compound assignment operator, this verifies |
| 3847 * assignment is valid. | 3732 * that the given assignment is valid. The [lhs] is the left hand side |
| 3733 * expression. The [rhs] is the right hand side expression. |
| 3848 * | 3734 * |
| 3849 * @param node the assignment expression being tested | |
| 3850 * @param lhs the left hand side expression | |
| 3851 * @param rhs the right hand side expression | |
| 3852 * @return `true` if and only if an error code is generated on the passed node | |
| 3853 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT]. | 3735 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT]. |
| 3854 */ | 3736 */ |
| 3855 bool _checkForInvalidCompoundAssignment( | 3737 bool _checkForInvalidCompoundAssignment( |
| 3856 AssignmentExpression node, Expression lhs, Expression rhs) { | 3738 AssignmentExpression node, Expression lhs, Expression rhs) { |
| 3857 if (lhs == null) { | 3739 if (lhs == null) { |
| 3858 return false; | 3740 return false; |
| 3859 } | 3741 } |
| 3860 VariableElement leftVariableElement = getVariableElement(lhs); | 3742 VariableElement leftVariableElement = getVariableElement(lhs); |
| 3861 DartType leftType = (leftVariableElement == null) | 3743 DartType leftType = (leftVariableElement == null) |
| 3862 ? getStaticType(lhs) | 3744 ? getStaticType(lhs) |
| 3863 : leftVariableElement.type; | 3745 : leftVariableElement.type; |
| 3864 MethodElement invokedMethod = node.staticElement; | 3746 MethodElement invokedMethod = node.staticElement; |
| 3865 if (invokedMethod == null) { | 3747 if (invokedMethod == null) { |
| 3866 return false; | 3748 return false; |
| 3867 } | 3749 } |
| 3868 DartType rightType = invokedMethod.type.returnType; | 3750 DartType rightType = invokedMethod.type.returnType; |
| 3869 if (leftType == null || rightType == null) { | 3751 if (leftType == null || rightType == null) { |
| 3870 return false; | 3752 return false; |
| 3871 } | 3753 } |
| 3872 if (!rightType.isAssignableTo(leftType)) { | 3754 if (!rightType.isAssignableTo(leftType)) { |
| 3873 _errorReporter.reportTypeErrorForNode( | 3755 _errorReporter.reportTypeErrorForNode( |
| 3874 StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightType, leftType]); | 3756 StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightType, leftType]); |
| 3875 return true; | 3757 return true; |
| 3876 } | 3758 } |
| 3877 return false; | 3759 return false; |
| 3878 } | 3760 } |
| 3879 | 3761 |
| 3880 /** | 3762 /** |
| 3881 * Check the given initializer to ensure that the field being initialized is a
valid field. | 3763 * Check the given [initializer] to ensure that the field being initialized is |
| 3882 * | 3764 * a valid field. The [fieldName] is the field name from the |
| 3883 * @param node the field initializer being checked | 3765 * [ConstructorFieldInitializer]. The [staticElement] is the static element |
| 3884 * @param fieldName the field name from the [ConstructorFieldInitializer] | 3766 * from the name in the [ConstructorFieldInitializer]. |
| 3885 * @param staticElement the static element from the name in the | |
| 3886 * [ConstructorFieldInitializer] | |
| 3887 */ | 3767 */ |
| 3888 void _checkForInvalidField(ConstructorFieldInitializer node, | 3768 void _checkForInvalidField(ConstructorFieldInitializer node, |
| 3889 SimpleIdentifier fieldName, Element staticElement) { | 3769 SimpleIdentifier fieldName, Element staticElement) { |
| 3890 if (staticElement is FieldElement) { | 3770 if (staticElement is FieldElement) { |
| 3891 FieldElement fieldElement = staticElement; | 3771 FieldElement fieldElement = staticElement; |
| 3892 if (fieldElement.isSynthetic) { | 3772 if (fieldElement.isSynthetic) { |
| 3893 _errorReporter.reportErrorForNode( | 3773 _errorReporter.reportErrorForNode( |
| 3894 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, | 3774 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, |
| 3895 [fieldName]); | 3775 [fieldName]); |
| 3896 } else if (fieldElement.isStatic) { | 3776 } else if (fieldElement.isStatic) { |
| 3897 _errorReporter.reportErrorForNode( | 3777 _errorReporter.reportErrorForNode( |
| 3898 CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, | 3778 CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, |
| 3899 [fieldName]); | 3779 [fieldName]); |
| 3900 } | 3780 } |
| 3901 } else { | 3781 } else { |
| 3902 _errorReporter.reportErrorForNode( | 3782 _errorReporter.reportErrorForNode( |
| 3903 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, | 3783 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, |
| 3904 [fieldName]); | 3784 [fieldName]); |
| 3905 return; | 3785 return; |
| 3906 } | 3786 } |
| 3907 } | 3787 } |
| 3908 | 3788 |
| 3909 /** | 3789 /** |
| 3910 * Check to see whether the given function body has a modifier associated with
it, and report it | 3790 * Check to see whether the given function [body] has a modifier associated |
| 3911 * as an error if it does. | 3791 * with it, and report it as an error if it does. |
| 3912 * | |
| 3913 * @param body the function body being checked | |
| 3914 * @param errorCode the error code to be reported if a modifier is found | |
| 3915 * @return `true` if an error was reported | |
| 3916 */ | 3792 */ |
| 3917 bool _checkForInvalidModifierOnBody( | 3793 bool _checkForInvalidModifierOnBody( |
| 3918 FunctionBody body, CompileTimeErrorCode errorCode) { | 3794 FunctionBody body, CompileTimeErrorCode errorCode) { |
| 3919 sc.Token keyword = body.keyword; | 3795 sc.Token keyword = body.keyword; |
| 3920 if (keyword != null) { | 3796 if (keyword != null) { |
| 3921 _errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]); | 3797 _errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]); |
| 3922 return true; | 3798 return true; |
| 3923 } | 3799 } |
| 3924 return false; | 3800 return false; |
| 3925 } | 3801 } |
| 3926 | 3802 |
| 3927 /** | 3803 /** |
| 3928 * This verifies that the usage of the passed 'this' is valid. | 3804 * Verify that the usage of the given 'this' is valid. |
| 3929 * | 3805 * |
| 3930 * @param node the 'this' expression to evaluate | |
| 3931 * @return `true` if and only if an error code is generated on the passed node | |
| 3932 * See [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]. | 3806 * See [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]. |
| 3933 */ | 3807 */ |
| 3934 bool _checkForInvalidReferenceToThis(ThisExpression node) { | 3808 bool _checkForInvalidReferenceToThis(ThisExpression node) { |
| 3935 if (!_isThisInValidContext(node)) { | 3809 if (!_isThisInValidContext(node)) { |
| 3936 _errorReporter.reportErrorForNode( | 3810 _errorReporter.reportErrorForNode( |
| 3937 CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, node); | 3811 CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, node); |
| 3938 return true; | 3812 return true; |
| 3939 } | 3813 } |
| 3940 return false; | 3814 return false; |
| 3941 } | 3815 } |
| 3942 | 3816 |
| 3943 /** | 3817 /** |
| 3944 * Checks to ensure that the passed [ListLiteral] or [MapLiteral] does not hav
e a type | 3818 * Checks to ensure that the given list of type [arguments] does not have a |
| 3945 * parameter as a type argument. | 3819 * type parameter as a type argument. The [errorCode] is either |
| 3946 * | 3820 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or |
| 3947 * @param arguments a non-`null`, non-empty [TypeName] node list from the resp
ective | 3821 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP]. |
| 3948 * [ListLiteral] or [MapLiteral] | |
| 3949 * @param errorCode either [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONS
T_LIST] or | |
| 3950 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP] | |
| 3951 * @return `true` if and only if an error code is generated on the passed node | |
| 3952 */ | 3822 */ |
| 3953 bool _checkForInvalidTypeArgumentInConstTypedLiteral( | 3823 bool _checkForInvalidTypeArgumentInConstTypedLiteral( |
| 3954 NodeList<TypeName> arguments, ErrorCode errorCode) { | 3824 NodeList<TypeName> arguments, ErrorCode errorCode) { |
| 3955 bool foundError = false; | 3825 bool foundError = false; |
| 3956 for (TypeName typeName in arguments) { | 3826 for (TypeName typeName in arguments) { |
| 3957 if (typeName.type is TypeParameterType) { | 3827 if (typeName.type is TypeParameterType) { |
| 3958 _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); | 3828 _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); |
| 3959 foundError = true; | 3829 foundError = true; |
| 3960 } | 3830 } |
| 3961 } | 3831 } |
| 3962 return foundError; | 3832 return foundError; |
| 3963 } | 3833 } |
| 3964 | 3834 |
| 3965 /** | 3835 /** |
| 3966 * This verifies that the elements given [ListLiteral] are subtypes of the spe
cified element | 3836 * Verify that the elements given [ListLiteral] are subtypes of the specified |
| 3967 * type. | 3837 * element type. The [typeArguments] are the type arguments. |
| 3968 * | 3838 * |
| 3969 * @param node the list literal to evaluate | |
| 3970 * @param typeArguments the type arguments, always non-`null` | |
| 3971 * @return `true` if and only if an error code is generated on the passed node | |
| 3972 * See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and | 3839 * See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and |
| 3973 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]. | 3840 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]. |
| 3974 */ | 3841 */ |
| 3975 bool _checkForListElementTypeNotAssignable( | 3842 bool _checkForListElementTypeNotAssignable( |
| 3976 ListLiteral node, TypeArgumentList typeArguments) { | 3843 ListLiteral node, TypeArgumentList typeArguments) { |
| 3977 NodeList<TypeName> typeNames = typeArguments.arguments; | 3844 NodeList<TypeName> typeNames = typeArguments.arguments; |
| 3978 if (typeNames.length < 1) { | 3845 if (typeNames.length < 1) { |
| 3979 return false; | 3846 return false; |
| 3980 } | 3847 } |
| 3981 DartType listElementType = typeNames[0].type; | 3848 DartType listElementType = typeNames[0].type; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3994 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(element, | 3861 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(element, |
| 3995 listElementType, | 3862 listElementType, |
| 3996 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { | 3863 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { |
| 3997 hasProblems = true; | 3864 hasProblems = true; |
| 3998 } | 3865 } |
| 3999 } | 3866 } |
| 4000 return hasProblems; | 3867 return hasProblems; |
| 4001 } | 3868 } |
| 4002 | 3869 |
| 4003 /** | 3870 /** |
| 4004 * This verifies that the key/value of entries of the given [MapLiteral] are s
ubtypes of the | 3871 * Verify that the key/value of entries of the given map [literal] are |
| 4005 * key/value types specified in the type arguments. | 3872 * subtypes of the key/value types specified in the type arguments. The |
| 3873 * [typeArguments] are the type arguments. |
| 4006 * | 3874 * |
| 4007 * @param node the map literal to evaluate | |
| 4008 * @param typeArguments the type arguments, always non-`null` | |
| 4009 * @return `true` if and only if an error code is generated on the passed node | |
| 4010 * See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], | 3875 * See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], |
| 4011 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], | 3876 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], |
| 4012 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and | 3877 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and |
| 4013 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. | 3878 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. |
| 4014 */ | 3879 */ |
| 4015 bool _checkForMapTypeNotAssignable( | 3880 bool _checkForMapTypeNotAssignable( |
| 4016 MapLiteral node, TypeArgumentList typeArguments) { | 3881 MapLiteral node, TypeArgumentList typeArguments) { |
| 4017 // Prepare maps key/value types. | 3882 // Prepare maps key/value types. |
| 4018 NodeList<TypeName> typeNames = typeArguments.arguments; | 3883 NodeList<TypeName> typeNames = typeArguments.arguments; |
| 4019 if (typeNames.length < 2) { | 3884 if (typeNames.length < 2) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 4046 } | 3911 } |
| 4047 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | 3912 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( |
| 4048 value, valueType, StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) { | 3913 value, valueType, StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) { |
| 4049 hasProblems = true; | 3914 hasProblems = true; |
| 4050 } | 3915 } |
| 4051 } | 3916 } |
| 4052 return hasProblems; | 3917 return hasProblems; |
| 4053 } | 3918 } |
| 4054 | 3919 |
| 4055 /** | 3920 /** |
| 4056 * This verifies that the [enclosingClass] does not define members with the sa
me name as | 3921 * Verify that the [enclosingClass] does not define members with the same name |
| 4057 * the enclosing class. | 3922 * as the enclosing class. |
| 4058 * | 3923 * |
| 4059 * @return `true` if and only if an error code is generated on the passed node | |
| 4060 * See [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]. | 3924 * See [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]. |
| 4061 */ | 3925 */ |
| 4062 bool _checkForMemberWithClassName() { | 3926 bool _checkForMemberWithClassName() { |
| 4063 if (_enclosingClass == null) { | 3927 if (_enclosingClass == null) { |
| 4064 return false; | 3928 return false; |
| 4065 } | 3929 } |
| 4066 String className = _enclosingClass.name; | 3930 String className = _enclosingClass.name; |
| 4067 if (className == null) { | 3931 if (className == null) { |
| 4068 return false; | 3932 return false; |
| 4069 } | 3933 } |
| 4070 bool problemReported = false; | 3934 bool problemReported = false; |
| 4071 // check accessors | 3935 // check accessors |
| 4072 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { | 3936 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { |
| 4073 if (className == accessor.name) { | 3937 if (className == accessor.name) { |
| 4074 _errorReporter.reportErrorForOffset( | 3938 _errorReporter.reportErrorForOffset( |
| 4075 CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME, accessor.nameOffset, | 3939 CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME, accessor.nameOffset, |
| 4076 className.length); | 3940 className.length); |
| 4077 problemReported = true; | 3941 problemReported = true; |
| 4078 } | 3942 } |
| 4079 } | 3943 } |
| 4080 // don't check methods, they would be constructors | 3944 // don't check methods, they would be constructors |
| 4081 // done | 3945 // done |
| 4082 return problemReported; | 3946 return problemReported; |
| 4083 } | 3947 } |
| 4084 | 3948 |
| 4085 /** | 3949 /** |
| 4086 * Check to make sure that all similarly typed accessors are of the same type
(including inherited | 3950 * Check to make sure that all similarly typed accessors are of the same type |
| 4087 * accessors). | 3951 * (including inherited accessors). |
| 4088 * | 3952 * |
| 4089 * @param node the accessor currently being visited | |
| 4090 * @return `true` if and only if an error code is generated on the passed node | |
| 4091 * See [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES], and | 3953 * See [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES], and |
| 4092 * [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE]. | 3954 * [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE]. |
| 4093 */ | 3955 */ |
| 4094 bool _checkForMismatchedAccessorTypes( | 3956 bool _checkForMismatchedAccessorTypes( |
| 4095 Declaration accessorDeclaration, String accessorTextName) { | 3957 Declaration accessorDeclaration, String accessorTextName) { |
| 4096 ExecutableElement accessorElement = | 3958 ExecutableElement accessorElement = |
| 4097 accessorDeclaration.element as ExecutableElement; | 3959 accessorDeclaration.element as ExecutableElement; |
| 4098 if (accessorElement is! PropertyAccessorElement) { | 3960 if (accessorElement is! PropertyAccessorElement) { |
| 4099 return false; | 3961 return false; |
| 4100 } | 3962 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4170 setterType, | 4032 setterType, |
| 4171 getterType, | 4033 getterType, |
| 4172 enclosingClassForCounterpart.displayName | 4034 enclosingClassForCounterpart.displayName |
| 4173 ]); | 4035 ]); |
| 4174 } | 4036 } |
| 4175 } | 4037 } |
| 4176 return false; | 4038 return false; |
| 4177 } | 4039 } |
| 4178 | 4040 |
| 4179 /** | 4041 /** |
| 4180 * Check to make sure that switch statements whose static type is an enum type
either have a | 4042 * Check to make sure that the given switch [statement] whose static type is |
| 4181 * default case or include all of the enum constants. | 4043 * an enum type either have a default case or include all of the enum |
| 4182 * | 4044 * constants. |
| 4183 * @param statement the switch statement to check | |
| 4184 * @return `true` if and only if an error code is generated on the passed node | |
| 4185 */ | 4045 */ |
| 4186 bool _checkForMissingEnumConstantInSwitch(SwitchStatement statement) { | 4046 bool _checkForMissingEnumConstantInSwitch(SwitchStatement statement) { |
| 4187 // TODO(brianwilkerson) This needs to be checked after constant values have | 4047 // TODO(brianwilkerson) This needs to be checked after constant values have |
| 4188 // been computed. | 4048 // been computed. |
| 4189 Expression expression = statement.expression; | 4049 Expression expression = statement.expression; |
| 4190 DartType expressionType = getStaticType(expression); | 4050 DartType expressionType = getStaticType(expression); |
| 4191 if (expressionType == null) { | 4051 if (expressionType == null) { |
| 4192 return false; | 4052 return false; |
| 4193 } | 4053 } |
| 4194 Element expressionElement = expressionType.element; | 4054 Element expressionElement = expressionType.element; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4226 } | 4086 } |
| 4227 for (int i = 0; i < nameCount; i++) { | 4087 for (int i = 0; i < nameCount; i++) { |
| 4228 _errorReporter.reportErrorForNode( | 4088 _errorReporter.reportErrorForNode( |
| 4229 CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, statement, | 4089 CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, statement, |
| 4230 [constantNames[i]]); | 4090 [constantNames[i]]); |
| 4231 } | 4091 } |
| 4232 return true; | 4092 return true; |
| 4233 } | 4093 } |
| 4234 | 4094 |
| 4235 /** | 4095 /** |
| 4236 * This verifies that the given function body does not contain return statemen
ts that both have | 4096 * Verify that the given function [body] does not contain return statements |
| 4237 * and do not have return values. | 4097 * that both have and do not have return values. |
| 4238 * | 4098 * |
| 4239 * @param node the function body being tested | |
| 4240 * @return `true` if and only if an error code is generated on the passed node | |
| 4241 * See [StaticWarningCode.MIXED_RETURN_TYPES]. | 4099 * See [StaticWarningCode.MIXED_RETURN_TYPES]. |
| 4242 */ | 4100 */ |
| 4243 bool _checkForMixedReturns(BlockFunctionBody node) { | 4101 bool _checkForMixedReturns(BlockFunctionBody node) { |
| 4244 if (_hasReturnWithoutValue) { | 4102 if (_hasReturnWithoutValue) { |
| 4245 return false; | 4103 return false; |
| 4246 } | 4104 } |
| 4247 int withCount = _returnsWith.length; | 4105 int withCount = _returnsWith.length; |
| 4248 int withoutCount = _returnsWithout.length; | 4106 int withoutCount = _returnsWithout.length; |
| 4249 if (withCount > 0 && withoutCount > 0) { | 4107 if (withCount > 0 && withoutCount > 0) { |
| 4250 for (int i = 0; i < withCount; i++) { | 4108 for (int i = 0; i < withCount; i++) { |
| 4251 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, | 4109 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, |
| 4252 _returnsWith[i].returnKeyword); | 4110 _returnsWith[i].returnKeyword); |
| 4253 } | 4111 } |
| 4254 for (int i = 0; i < withoutCount; i++) { | 4112 for (int i = 0; i < withoutCount; i++) { |
| 4255 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, | 4113 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, |
| 4256 _returnsWithout[i].returnKeyword); | 4114 _returnsWithout[i].returnKeyword); |
| 4257 } | 4115 } |
| 4258 return true; | 4116 return true; |
| 4259 } | 4117 } |
| 4260 return false; | 4118 return false; |
| 4261 } | 4119 } |
| 4262 | 4120 |
| 4263 /** | 4121 /** |
| 4264 * This verifies that the passed mixin does not have an explicitly declared co
nstructor. | 4122 * Verify that the given mixin does not have an explicitly declared |
| 4123 * constructor. The [mixinName] is the node to report problem on. The |
| 4124 * [mixinElement] is the mixing to evaluate. |
| 4265 * | 4125 * |
| 4266 * @param mixinName the node to report problem on | |
| 4267 * @param mixinElement the mixing to evaluate | |
| 4268 * @return `true` if and only if an error code is generated on the passed node | |
| 4269 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]. | 4126 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]. |
| 4270 */ | 4127 */ |
| 4271 bool _checkForMixinDeclaresConstructor( | 4128 bool _checkForMixinDeclaresConstructor( |
| 4272 TypeName mixinName, ClassElement mixinElement) { | 4129 TypeName mixinName, ClassElement mixinElement) { |
| 4273 for (ConstructorElement constructor in mixinElement.constructors) { | 4130 for (ConstructorElement constructor in mixinElement.constructors) { |
| 4274 if (!constructor.isSynthetic && !constructor.isFactory) { | 4131 if (!constructor.isSynthetic && !constructor.isFactory) { |
| 4275 _errorReporter.reportErrorForNode( | 4132 _errorReporter.reportErrorForNode( |
| 4276 CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, mixinName, | 4133 CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, mixinName, |
| 4277 [mixinElement.name]); | 4134 [mixinElement.name]); |
| 4278 return true; | 4135 return true; |
| 4279 } | 4136 } |
| 4280 } | 4137 } |
| 4281 return false; | 4138 return false; |
| 4282 } | 4139 } |
| 4283 | 4140 |
| 4284 /** | 4141 /** |
| 4285 * This verifies that the passed mixin has the 'Object' superclass. | 4142 * Verify that the given mixin has the 'Object' superclass. The [mixinName] is |
| 4143 * the node to report problem on. The [mixinElement] is the mixing to |
| 4144 * evaluate. |
| 4286 * | 4145 * |
| 4287 * @param mixinName the node to report problem on | |
| 4288 * @param mixinElement the mixing to evaluate | |
| 4289 * @return `true` if and only if an error code is generated on the passed node | |
| 4290 * See [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]. | 4146 * See [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]. |
| 4291 */ | 4147 */ |
| 4292 bool _checkForMixinInheritsNotFromObject( | 4148 bool _checkForMixinInheritsNotFromObject( |
| 4293 TypeName mixinName, ClassElement mixinElement) { | 4149 TypeName mixinName, ClassElement mixinElement) { |
| 4294 InterfaceType mixinSupertype = mixinElement.supertype; | 4150 InterfaceType mixinSupertype = mixinElement.supertype; |
| 4295 if (mixinSupertype != null) { | 4151 if (mixinSupertype != null) { |
| 4296 if (!mixinSupertype.isObject || | 4152 if (!mixinSupertype.isObject || |
| 4297 !mixinElement.isTypedef && mixinElement.mixins.length != 0) { | 4153 !mixinElement.isTypedef && mixinElement.mixins.length != 0) { |
| 4298 _errorReporter.reportErrorForNode( | 4154 _errorReporter.reportErrorForNode( |
| 4299 CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, mixinName, | 4155 CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, mixinName, |
| 4300 [mixinElement.name]); | 4156 [mixinElement.name]); |
| 4301 return true; | 4157 return true; |
| 4302 } | 4158 } |
| 4303 } | 4159 } |
| 4304 return false; | 4160 return false; |
| 4305 } | 4161 } |
| 4306 | 4162 |
| 4307 /** | 4163 /** |
| 4308 * This verifies that the passed mixin does not reference 'super'. | 4164 * Verify that the given mixin does not reference 'super'. The [mixinName] is |
| 4165 * the node to report problem on. The [mixinElement] is the mixing to |
| 4166 * evaluate. |
| 4309 * | 4167 * |
| 4310 * @param mixinName the node to report problem on | |
| 4311 * @param mixinElement the mixing to evaluate | |
| 4312 * @return `true` if and only if an error code is generated on the passed node | |
| 4313 * See [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]. | 4168 * See [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]. |
| 4314 */ | 4169 */ |
| 4315 bool _checkForMixinReferencesSuper( | 4170 bool _checkForMixinReferencesSuper( |
| 4316 TypeName mixinName, ClassElement mixinElement) { | 4171 TypeName mixinName, ClassElement mixinElement) { |
| 4317 if (mixinElement.hasReferenceToSuper) { | 4172 if (mixinElement.hasReferenceToSuper) { |
| 4318 _errorReporter.reportErrorForNode( | 4173 _errorReporter.reportErrorForNode( |
| 4319 CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, mixinName, | 4174 CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, mixinName, |
| 4320 [mixinElement.name]); | 4175 [mixinElement.name]); |
| 4321 } | 4176 } |
| 4322 return false; | 4177 return false; |
| 4323 } | 4178 } |
| 4324 | 4179 |
| 4325 /** | 4180 /** |
| 4326 * This verifies that the passed constructor has at most one 'super' initializ
er. | 4181 * Verify that the given [constructor] has at most one 'super' initializer. |
| 4327 * | 4182 * |
| 4328 * @param node the constructor declaration to evaluate | |
| 4329 * @return `true` if and only if an error code is generated on the passed node | |
| 4330 * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]. | 4183 * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]. |
| 4331 */ | 4184 */ |
| 4332 bool _checkForMultipleSuperInitializers(ConstructorDeclaration node) { | 4185 bool _checkForMultipleSuperInitializers(ConstructorDeclaration node) { |
| 4333 int numSuperInitializers = 0; | 4186 int numSuperInitializers = 0; |
| 4334 for (ConstructorInitializer initializer in node.initializers) { | 4187 for (ConstructorInitializer initializer in node.initializers) { |
| 4335 if (initializer is SuperConstructorInvocation) { | 4188 if (initializer is SuperConstructorInvocation) { |
| 4336 numSuperInitializers++; | 4189 numSuperInitializers++; |
| 4337 if (numSuperInitializers > 1) { | 4190 if (numSuperInitializers > 1) { |
| 4338 _errorReporter.reportErrorForNode( | 4191 _errorReporter.reportErrorForNode( |
| 4339 CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer); | 4192 CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer); |
| 4340 } | 4193 } |
| 4341 } | 4194 } |
| 4342 } | 4195 } |
| 4343 return numSuperInitializers > 0; | 4196 return numSuperInitializers > 0; |
| 4344 } | 4197 } |
| 4345 | 4198 |
| 4346 /** | 4199 /** |
| 4347 * Checks to ensure that native function bodies can only in SDK code. | 4200 * Checks to ensure that the given native function [body] is in SDK code. |
| 4348 * | 4201 * |
| 4349 * @param node the native function body to test | |
| 4350 * @return `true` if and only if an error code is generated on the passed node | |
| 4351 * See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]. | 4202 * See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]. |
| 4352 */ | 4203 */ |
| 4353 bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) { | 4204 bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) { |
| 4354 if (!_isInSystemLibrary && !_hasExtUri) { | 4205 if (!_isInSystemLibrary && !_hasExtUri) { |
| 4355 _errorReporter.reportErrorForNode( | 4206 _errorReporter.reportErrorForNode( |
| 4356 ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, node); | 4207 ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, node); |
| 4357 return true; | 4208 return true; |
| 4358 } | 4209 } |
| 4359 return false; | 4210 return false; |
| 4360 } | 4211 } |
| 4361 | 4212 |
| 4362 /** | 4213 /** |
| 4363 * This verifies that the passed 'new' instance creation expression invokes ex
isting constructor. | 4214 * Verify that the given instance creation [expression] invokes an existing |
| 4215 * constructor. The [constructorName] is the constructor name. The [typeName] |
| 4216 * is the name of the type defining the constructor. |
| 4364 * | 4217 * |
| 4365 * This method assumes that the instance creation was tested to be 'new' befor
e being called. | 4218 * This method assumes that the instance creation was tested to be 'new' |
| 4219 * before being called. |
| 4366 * | 4220 * |
| 4367 * @param node the instance creation expression to evaluate | |
| 4368 * @param constructorName the constructor name, always non-`null` | |
| 4369 * @param typeName the name of the type defining the constructor, always non-`
null` | |
| 4370 * @return `true` if and only if an error code is generated on the passed node | |
| 4371 * See [StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR]. | 4221 * See [StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR]. |
| 4372 */ | 4222 */ |
| 4373 bool _checkForNewWithUndefinedConstructor(InstanceCreationExpression node, | 4223 bool _checkForNewWithUndefinedConstructor(InstanceCreationExpression node, |
| 4374 ConstructorName constructorName, TypeName typeName) { | 4224 ConstructorName constructorName, TypeName typeName) { |
| 4375 // OK if resolved | 4225 // OK if resolved |
| 4376 if (node.staticElement != null) { | 4226 if (node.staticElement != null) { |
| 4377 return false; | 4227 return false; |
| 4378 } | 4228 } |
| 4379 DartType type = typeName.type; | 4229 DartType type = typeName.type; |
| 4380 if (type is InterfaceType) { | 4230 if (type is InterfaceType) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4396 ]); | 4246 ]); |
| 4397 } else { | 4247 } else { |
| 4398 _errorReporter.reportErrorForNode( | 4248 _errorReporter.reportErrorForNode( |
| 4399 StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, | 4249 StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, |
| 4400 constructorName, [className]); | 4250 constructorName, [className]); |
| 4401 } | 4251 } |
| 4402 return true; | 4252 return true; |
| 4403 } | 4253 } |
| 4404 | 4254 |
| 4405 /** | 4255 /** |
| 4406 * This checks that if the passed class declaration implicitly calls default c
onstructor of its | 4256 * Check that if the given class [declaration] implicitly calls default |
| 4407 * superclass, there should be such default constructor - implicit or explicit
. | 4257 * constructor of its superclass, there should be such default constructor - |
| 4258 * implicit or explicit. |
| 4408 * | 4259 * |
| 4409 * @param node the [ClassDeclaration] to evaluate | |
| 4410 * @return `true` if and only if an error code is generated on the passed node | |
| 4411 * See [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]. | 4260 * See [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]. |
| 4412 */ | 4261 */ |
| 4413 bool _checkForNoDefaultSuperConstructorImplicit(ClassDeclaration node) { | 4262 bool _checkForNoDefaultSuperConstructorImplicit(ClassDeclaration node) { |
| 4414 // do nothing if mixin errors have already been reported for this class. | 4263 // do nothing if mixin errors have already been reported for this class. |
| 4415 ClassElementImpl enclosingClass = _enclosingClass; | 4264 ClassElementImpl enclosingClass = _enclosingClass; |
| 4416 if (enclosingClass.mixinErrorsReported) { | 4265 if (enclosingClass.mixinErrorsReported) { |
| 4417 return false; | 4266 return false; |
| 4418 } | 4267 } |
| 4419 // do nothing if there is explicit constructor | 4268 // do nothing if there is explicit constructor |
| 4420 List<ConstructorElement> constructors = _enclosingClass.constructors; | 4269 List<ConstructorElement> constructors = _enclosingClass.constructors; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 4444 } | 4293 } |
| 4445 } | 4294 } |
| 4446 // report problem | 4295 // report problem |
| 4447 _errorReporter.reportErrorForNode( | 4296 _errorReporter.reportErrorForNode( |
| 4448 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, node.name, | 4297 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, node.name, |
| 4449 [superType.displayName]); | 4298 [superType.displayName]); |
| 4450 return true; | 4299 return true; |
| 4451 } | 4300 } |
| 4452 | 4301 |
| 4453 /** | 4302 /** |
| 4454 * This checks that passed class declaration overrides all members required by
its superclasses | 4303 * Check that the given class declaration overrides all members required by |
| 4455 * and interfaces. | 4304 * its superclasses and interfaces. The [classNameNode] is the |
| 4305 * [SimpleIdentifier] to be used if there is a violation, this is either the |
| 4306 * named from the [ClassDeclaration] or from the [ClassTypeAlias]. |
| 4456 * | 4307 * |
| 4457 * @param classNameNode the [SimpleIdentifier] to be used if there is a violat
ion, this is | |
| 4458 * either the named from the [ClassDeclaration] or from the [ClassTyp
eAlias]. | |
| 4459 * @return `true` if and only if an error code is generated on the passed node | |
| 4460 * See [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], | 4308 * See [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], |
| 4461 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO], | 4309 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO], |
| 4462 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE], | 4310 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE], |
| 4463 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR], and | 4311 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR], and |
| 4464 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS]. | 4312 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS]. |
| 4465 */ | 4313 */ |
| 4466 bool _checkForNonAbstractClassInheritsAbstractMember( | 4314 bool _checkForNonAbstractClassInheritsAbstractMember( |
| 4467 SimpleIdentifier classNameNode) { | 4315 SimpleIdentifier classNameNode) { |
| 4468 if (_enclosingClass.isAbstract) { | 4316 if (_enclosingClass.isAbstract) { |
| 4469 return false; | 4317 return false; |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4622 stringMembersArray.length - 4 | 4470 stringMembersArray.length - 4 |
| 4623 ]); | 4471 ]); |
| 4624 } | 4472 } |
| 4625 analysisError.setProperty( | 4473 analysisError.setProperty( |
| 4626 ErrorProperty.UNIMPLEMENTED_METHODS, missingOverridesArray); | 4474 ErrorProperty.UNIMPLEMENTED_METHODS, missingOverridesArray); |
| 4627 _errorReporter.reportError(analysisError); | 4475 _errorReporter.reportError(analysisError); |
| 4628 return true; | 4476 return true; |
| 4629 } | 4477 } |
| 4630 | 4478 |
| 4631 /** | 4479 /** |
| 4632 * Checks to ensure that the expressions that need to be of type bool, are. Ot
herwise an error is | 4480 * Check to ensure that the [condition] is of type bool, are. Otherwise an |
| 4633 * reported on the expression. | 4481 * error is reported on the expression. |
| 4634 * | 4482 * |
| 4635 * @param condition the conditional expression to test | |
| 4636 * @return `true` if and only if an error code is generated on the passed node | |
| 4637 * See [StaticTypeWarningCode.NON_BOOL_CONDITION]. | 4483 * See [StaticTypeWarningCode.NON_BOOL_CONDITION]. |
| 4638 */ | 4484 */ |
| 4639 bool _checkForNonBoolCondition(Expression condition) { | 4485 bool _checkForNonBoolCondition(Expression condition) { |
| 4640 DartType conditionType = getStaticType(condition); | 4486 DartType conditionType = getStaticType(condition); |
| 4641 if (conditionType != null && !conditionType.isAssignableTo(_boolType)) { | 4487 if (conditionType != null && !conditionType.isAssignableTo(_boolType)) { |
| 4642 _errorReporter.reportErrorForNode( | 4488 _errorReporter.reportErrorForNode( |
| 4643 StaticTypeWarningCode.NON_BOOL_CONDITION, condition); | 4489 StaticTypeWarningCode.NON_BOOL_CONDITION, condition); |
| 4644 return true; | 4490 return true; |
| 4645 } | 4491 } |
| 4646 return false; | 4492 return false; |
| 4647 } | 4493 } |
| 4648 | 4494 |
| 4649 /** | 4495 /** |
| 4650 * This verifies that the passed assert statement has either a 'bool' or '() -
> bool' input. | 4496 * Verify that the given assert [statement] has either a 'bool' or |
| 4497 * '() -> bool' input. |
| 4651 * | 4498 * |
| 4652 * @param node the assert statement to evaluate | |
| 4653 * @return `true` if and only if an error code is generated on the passed node | |
| 4654 * See [StaticTypeWarningCode.NON_BOOL_EXPRESSION]. | 4499 * See [StaticTypeWarningCode.NON_BOOL_EXPRESSION]. |
| 4655 */ | 4500 */ |
| 4656 bool _checkForNonBoolExpression(AssertStatement node) { | 4501 bool _checkForNonBoolExpression(AssertStatement node) { |
| 4657 Expression expression = node.condition; | 4502 Expression expression = node.condition; |
| 4658 DartType type = getStaticType(expression); | 4503 DartType type = getStaticType(expression); |
| 4659 if (type is InterfaceType) { | 4504 if (type is InterfaceType) { |
| 4660 if (!type.isAssignableTo(_boolType)) { | 4505 if (!type.isAssignableTo(_boolType)) { |
| 4661 _errorReporter.reportErrorForNode( | 4506 _errorReporter.reportErrorForNode( |
| 4662 StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression); | 4507 StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression); |
| 4663 return true; | 4508 return true; |
| 4664 } | 4509 } |
| 4665 } else if (type is FunctionType) { | 4510 } else if (type is FunctionType) { |
| 4666 FunctionType functionType = type; | 4511 FunctionType functionType = type; |
| 4667 if (functionType.typeArguments.length == 0 && | 4512 if (functionType.typeArguments.length == 0 && |
| 4668 !functionType.returnType.isAssignableTo(_boolType)) { | 4513 !functionType.returnType.isAssignableTo(_boolType)) { |
| 4669 _errorReporter.reportErrorForNode( | 4514 _errorReporter.reportErrorForNode( |
| 4670 StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression); | 4515 StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression); |
| 4671 return true; | 4516 return true; |
| 4672 } | 4517 } |
| 4673 } | 4518 } |
| 4674 return false; | 4519 return false; |
| 4675 } | 4520 } |
| 4676 | 4521 |
| 4677 /** | 4522 /** |
| 4678 * Checks to ensure that the given expression is assignable to bool. | 4523 * Checks to ensure that the given [expression] is assignable to bool. |
| 4679 * | 4524 * |
| 4680 * @param expression the expression expression to test | |
| 4681 * @return `true` if and only if an error code is generated on the passed node | |
| 4682 * See [StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION]. | 4525 * See [StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION]. |
| 4683 */ | 4526 */ |
| 4684 bool _checkForNonBoolNegationExpression(Expression expression) { | 4527 bool _checkForNonBoolNegationExpression(Expression expression) { |
| 4685 DartType conditionType = getStaticType(expression); | 4528 DartType conditionType = getStaticType(expression); |
| 4686 if (conditionType != null && !conditionType.isAssignableTo(_boolType)) { | 4529 if (conditionType != null && !conditionType.isAssignableTo(_boolType)) { |
| 4687 _errorReporter.reportErrorForNode( | 4530 _errorReporter.reportErrorForNode( |
| 4688 StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression); | 4531 StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression); |
| 4689 return true; | 4532 return true; |
| 4690 } | 4533 } |
| 4691 return false; | 4534 return false; |
| 4692 } | 4535 } |
| 4693 | 4536 |
| 4694 /** | 4537 /** |
| 4695 * This verifies the passed map literal either: | 4538 * Verify the given map [literal] either: |
| 4696 * * has `const modifier` | 4539 * * has `const modifier` |
| 4697 * * has explicit type arguments | 4540 * * has explicit type arguments |
| 4698 * * is not start of the statement | 4541 * * is not start of the statement |
| 4699 * | 4542 * |
| 4700 * @param node the map literal to evaluate | |
| 4701 * @return `true` if and only if an error code is generated on the passed node | |
| 4702 * See [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]. | 4543 * See [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]. |
| 4703 */ | 4544 */ |
| 4704 bool _checkForNonConstMapAsExpressionStatement(MapLiteral node) { | 4545 bool _checkForNonConstMapAsExpressionStatement(MapLiteral node) { |
| 4705 // "const" | 4546 // "const" |
| 4706 if (node.constKeyword != null) { | 4547 if (node.constKeyword != null) { |
| 4707 return false; | 4548 return false; |
| 4708 } | 4549 } |
| 4709 // has type arguments | 4550 // has type arguments |
| 4710 if (node.typeArguments != null) { | 4551 if (node.typeArguments != null) { |
| 4711 return false; | 4552 return false; |
| 4712 } | 4553 } |
| 4713 // prepare statement | 4554 // prepare statement |
| 4714 Statement statement = | 4555 Statement statement = |
| 4715 node.getAncestor((node) => node is ExpressionStatement); | 4556 node.getAncestor((node) => node is ExpressionStatement); |
| 4716 if (statement == null) { | 4557 if (statement == null) { |
| 4717 return false; | 4558 return false; |
| 4718 } | 4559 } |
| 4719 // OK, statement does not start with map | 4560 // OK, statement does not start with map |
| 4720 if (!identical(statement.beginToken, node.beginToken)) { | 4561 if (!identical(statement.beginToken, node.beginToken)) { |
| 4721 return false; | 4562 return false; |
| 4722 } | 4563 } |
| 4723 // report problem | 4564 // report problem |
| 4724 _errorReporter.reportErrorForNode( | 4565 _errorReporter.reportErrorForNode( |
| 4725 CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, node); | 4566 CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, node); |
| 4726 return true; | 4567 return true; |
| 4727 } | 4568 } |
| 4728 | 4569 |
| 4729 /** | 4570 /** |
| 4730 * This verifies the passed method declaration of operator `[]=`, has `void` r
eturn | 4571 * Verify that the given method [declaration] of operator `[]=`, has `void` |
| 4731 * type. | 4572 * return type. |
| 4732 * | 4573 * |
| 4733 * @param node the method declaration to evaluate | |
| 4734 * @return `true` if and only if an error code is generated on the passed node | |
| 4735 * See [StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR]. | 4574 * See [StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR]. |
| 4736 */ | 4575 */ |
| 4737 bool _checkForNonVoidReturnTypeForOperator(MethodDeclaration node) { | 4576 bool _checkForNonVoidReturnTypeForOperator(MethodDeclaration node) { |
| 4738 // check that []= operator | 4577 // check that []= operator |
| 4739 SimpleIdentifier name = node.name; | 4578 SimpleIdentifier name = node.name; |
| 4740 if (name.name != "[]=") { | 4579 if (name.name != "[]=") { |
| 4741 return false; | 4580 return false; |
| 4742 } | 4581 } |
| 4743 // check return type | 4582 // check return type |
| 4744 TypeName typeName = node.returnType; | 4583 TypeName typeName = node.returnType; |
| 4745 if (typeName != null) { | 4584 if (typeName != null) { |
| 4746 DartType type = typeName.type; | 4585 DartType type = typeName.type; |
| 4747 if (type != null && !type.isVoid) { | 4586 if (type != null && !type.isVoid) { |
| 4748 _errorReporter.reportErrorForNode( | 4587 _errorReporter.reportErrorForNode( |
| 4749 StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, typeName); | 4588 StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, typeName); |
| 4750 } | 4589 } |
| 4751 } | 4590 } |
| 4752 // no warning | 4591 // no warning |
| 4753 return false; | 4592 return false; |
| 4754 } | 4593 } |
| 4755 | 4594 |
| 4756 /** | 4595 /** |
| 4757 * This verifies the passed setter has no return type or the `void` return typ
e. | 4596 * Verify the given setter has no return type or the `void` return type. |
| 4758 * | 4597 * |
| 4759 * @param typeName the type name to evaluate | |
| 4760 * @return `true` if and only if an error code is generated on the passed node | |
| 4761 * See [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER]. | 4598 * See [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER]. |
| 4762 */ | 4599 */ |
| 4763 bool _checkForNonVoidReturnTypeForSetter(TypeName typeName) { | 4600 bool _checkForNonVoidReturnTypeForSetter(TypeName typeName) { |
| 4764 if (typeName != null) { | 4601 if (typeName != null) { |
| 4765 DartType type = typeName.type; | 4602 DartType type = typeName.type; |
| 4766 if (type != null && !type.isVoid) { | 4603 if (type != null && !type.isVoid) { |
| 4767 _errorReporter.reportErrorForNode( | 4604 _errorReporter.reportErrorForNode( |
| 4768 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, typeName); | 4605 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, typeName); |
| 4769 } | 4606 } |
| 4770 } | 4607 } |
| 4771 return false; | 4608 return false; |
| 4772 } | 4609 } |
| 4773 | 4610 |
| 4774 /** | 4611 /** |
| 4775 * This verifies the passed operator-method declaration, does not have an opti
onal parameter. | 4612 * Verify the given operator-method [declaration], does not have an optional |
| 4613 * parameter. This method assumes that the method declaration was tested to be |
| 4614 * an operator declaration before being called. |
| 4776 * | 4615 * |
| 4777 * This method assumes that the method declaration was tested to be an operato
r declaration before | |
| 4778 * being called. | |
| 4779 * | |
| 4780 * @param node the method declaration to evaluate | |
| 4781 * @return `true` if and only if an error code is generated on the passed node | |
| 4782 * See [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]. | 4616 * See [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]. |
| 4783 */ | 4617 */ |
| 4784 bool _checkForOptionalParameterInOperator(MethodDeclaration node) { | 4618 bool _checkForOptionalParameterInOperator(MethodDeclaration node) { |
| 4785 FormalParameterList parameterList = node.parameters; | 4619 FormalParameterList parameterList = node.parameters; |
| 4786 if (parameterList == null) { | 4620 if (parameterList == null) { |
| 4787 return false; | 4621 return false; |
| 4788 } | 4622 } |
| 4789 bool foundError = false; | 4623 bool foundError = false; |
| 4790 NodeList<FormalParameter> formalParameters = parameterList.parameters; | 4624 NodeList<FormalParameter> formalParameters = parameterList.parameters; |
| 4791 for (FormalParameter formalParameter in formalParameters) { | 4625 for (FormalParameter formalParameter in formalParameters) { |
| 4792 if (formalParameter.kind.isOptional) { | 4626 if (formalParameter.kind.isOptional) { |
| 4793 _errorReporter.reportErrorForNode( | 4627 _errorReporter.reportErrorForNode( |
| 4794 CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, | 4628 CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, |
| 4795 formalParameter); | 4629 formalParameter); |
| 4796 foundError = true; | 4630 foundError = true; |
| 4797 } | 4631 } |
| 4798 } | 4632 } |
| 4799 return foundError; | 4633 return foundError; |
| 4800 } | 4634 } |
| 4801 | 4635 |
| 4802 /** | 4636 /** |
| 4803 * This checks for named optional parameters that begin with '_'. | 4637 * Check that the given named optional [parameter] does not begin with '_'. |
| 4804 * | 4638 * |
| 4805 * @param node the default formal parameter to evaluate | |
| 4806 * @return `true` if and only if an error code is generated on the passed node | |
| 4807 * See [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]. | 4639 * See [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]. |
| 4808 */ | 4640 */ |
| 4809 bool _checkForPrivateOptionalParameter(FormalParameter node) { | 4641 bool _checkForPrivateOptionalParameter(FormalParameter node) { |
| 4810 // should be named parameter | 4642 // should be named parameter |
| 4811 if (node.kind != ParameterKind.NAMED) { | 4643 if (node.kind != ParameterKind.NAMED) { |
| 4812 return false; | 4644 return false; |
| 4813 } | 4645 } |
| 4814 // name should start with '_' | 4646 // name should start with '_' |
| 4815 SimpleIdentifier name = node.identifier; | 4647 SimpleIdentifier name = node.identifier; |
| 4816 if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) { | 4648 if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) { |
| 4817 return false; | 4649 return false; |
| 4818 } | 4650 } |
| 4819 // report problem | 4651 // report problem |
| 4820 _errorReporter.reportErrorForNode( | 4652 _errorReporter.reportErrorForNode( |
| 4821 CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, node); | 4653 CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, node); |
| 4822 return true; | 4654 return true; |
| 4823 } | 4655 } |
| 4824 | 4656 |
| 4825 /** | 4657 /** |
| 4826 * This checks if the passed constructor declaration is the redirecting genera
tive constructor and | 4658 * Check whether the given constructor [declaration] is the redirecting |
| 4827 * references itself directly or indirectly. | 4659 * generative constructor and references itself directly or indirectly. The |
| 4660 * [constructorElement] is the constructor element. |
| 4828 * | 4661 * |
| 4829 * @param node the constructor declaration to evaluate | |
| 4830 * @param constructorElement the constructor element | |
| 4831 * @return `true` if and only if an error code is generated on the passed node | |
| 4832 * See [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]. | 4662 * See [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]. |
| 4833 */ | 4663 */ |
| 4834 bool _checkForRecursiveConstructorRedirect( | 4664 bool _checkForRecursiveConstructorRedirect( |
| 4835 ConstructorDeclaration node, ConstructorElement constructorElement) { | 4665 ConstructorDeclaration node, ConstructorElement constructorElement) { |
| 4836 // we check generative constructor here | 4666 // we check generative constructor here |
| 4837 if (node.factoryKeyword != null) { | 4667 if (node.factoryKeyword != null) { |
| 4838 return false; | 4668 return false; |
| 4839 } | 4669 } |
| 4840 // try to find redirecting constructor invocation and analyzer it for | 4670 // try to find redirecting constructor invocation and analyzer it for |
| 4841 // recursion | 4671 // recursion |
| 4842 for (ConstructorInitializer initializer in node.initializers) { | 4672 for (ConstructorInitializer initializer in node.initializers) { |
| 4843 if (initializer is RedirectingConstructorInvocation) { | 4673 if (initializer is RedirectingConstructorInvocation) { |
| 4844 // OK if no cycle | 4674 // OK if no cycle |
| 4845 if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) { | 4675 if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) { |
| 4846 return false; | 4676 return false; |
| 4847 } | 4677 } |
| 4848 // report error | 4678 // report error |
| 4849 _errorReporter.reportErrorForNode( | 4679 _errorReporter.reportErrorForNode( |
| 4850 CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer); | 4680 CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer); |
| 4851 return true; | 4681 return true; |
| 4852 } | 4682 } |
| 4853 } | 4683 } |
| 4854 // OK, no redirecting constructor invocation | 4684 // OK, no redirecting constructor invocation |
| 4855 return false; | 4685 return false; |
| 4856 } | 4686 } |
| 4857 | 4687 |
| 4858 /** | 4688 /** |
| 4859 * This checks if the passed constructor declaration has redirected constructo
r and references | 4689 * Check whether the given constructor [declaration] has redirected |
| 4860 * itself directly or indirectly. | 4690 * constructor and references itself directly or indirectly. The |
| 4691 * [constructorElement] is the constructor element. |
| 4861 * | 4692 * |
| 4862 * @param node the constructor declaration to evaluate | |
| 4863 * @param constructorElement the constructor element | |
| 4864 * @return `true` if and only if an error code is generated on the passed node | |
| 4865 * See [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]. | 4693 * See [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]. |
| 4866 */ | 4694 */ |
| 4867 bool _checkForRecursiveFactoryRedirect( | 4695 bool _checkForRecursiveFactoryRedirect( |
| 4868 ConstructorDeclaration node, ConstructorElement constructorElement) { | 4696 ConstructorDeclaration node, ConstructorElement constructorElement) { |
| 4869 // prepare redirected constructor | 4697 // prepare redirected constructor |
| 4870 ConstructorName redirectedConstructorNode = node.redirectedConstructor; | 4698 ConstructorName redirectedConstructorNode = node.redirectedConstructor; |
| 4871 if (redirectedConstructorNode == null) { | 4699 if (redirectedConstructorNode == null) { |
| 4872 return false; | 4700 return false; |
| 4873 } | 4701 } |
| 4874 // OK if no cycle | 4702 // OK if no cycle |
| 4875 if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) { | 4703 if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) { |
| 4876 return false; | 4704 return false; |
| 4877 } | 4705 } |
| 4878 // report error | 4706 // report error |
| 4879 _errorReporter.reportErrorForNode( | 4707 _errorReporter.reportErrorForNode( |
| 4880 CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT, | 4708 CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT, |
| 4881 redirectedConstructorNode); | 4709 redirectedConstructorNode); |
| 4882 return true; | 4710 return true; |
| 4883 } | 4711 } |
| 4884 | 4712 |
| 4885 /** | 4713 /** |
| 4886 * This checks the class declaration is not a superinterface to itself. | 4714 * Check that the class [element] is not a superinterface to itself. |
| 4887 * | 4715 * |
| 4888 * @param classElt the class element to test | |
| 4889 * @return `true` if and only if an error code is generated on the passed elem
ent | |
| 4890 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], | 4716 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], |
| 4891 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], a
nd | 4717 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], a
nd |
| 4892 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]
. | 4718 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]
. |
| 4893 */ | 4719 */ |
| 4894 bool _checkForRecursiveInterfaceInheritance(ClassElement classElt) { | 4720 bool _checkForRecursiveInterfaceInheritance(ClassElement classElt) { |
| 4895 if (classElt == null) { | 4721 if (classElt == null) { |
| 4896 return false; | 4722 return false; |
| 4897 } | 4723 } |
| 4898 return _safeCheckForRecursiveInterfaceInheritance( | 4724 return _safeCheckForRecursiveInterfaceInheritance( |
| 4899 classElt, new List<ClassElement>()); | 4725 classElt, new List<ClassElement>()); |
| 4900 } | 4726 } |
| 4901 | 4727 |
| 4902 /** | 4728 /** |
| 4903 * This checks the passed constructor declaration has a valid combination of r
edirected | 4729 * Check that the given constructor [declaration] has a valid combination of |
| 4904 * constructor invocation(s), super constructor invocations and field initiali
zers. | 4730 * redirected constructor invocation(s), super constructor invocations and |
| 4731 * field initializers. |
| 4905 * | 4732 * |
| 4906 * @param node the constructor declaration to evaluate | |
| 4907 * @return `true` if and only if an error code is generated on the passed node | |
| 4908 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR]
, | 4733 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR]
, |
| 4909 * [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR], | 4734 * [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR], |
| 4910 * [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS], | 4735 * [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS], |
| 4911 * [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR], and | 4736 * [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR], and |
| 4912 * [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR]. | 4737 * [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR]. |
| 4913 */ | 4738 */ |
| 4914 bool _checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) { | 4739 bool _checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) { |
| 4915 bool errorReported = false; | 4740 bool errorReported = false; |
| 4916 // | 4741 // |
| 4917 // Check for default values in the parameters | 4742 // Check for default values in the parameters |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4976 initializer); | 4801 initializer); |
| 4977 errorReported = true; | 4802 errorReported = true; |
| 4978 } | 4803 } |
| 4979 } | 4804 } |
| 4980 } | 4805 } |
| 4981 // done | 4806 // done |
| 4982 return errorReported; | 4807 return errorReported; |
| 4983 } | 4808 } |
| 4984 | 4809 |
| 4985 /** | 4810 /** |
| 4986 * This checks if the passed constructor declaration has redirected constructo
r and references | 4811 * Check whether the given constructor [declaration] has redirected |
| 4987 * itself directly or indirectly. | 4812 * constructor and references itself directly or indirectly. The |
| 4813 * [constructorElement] is the constructor element. |
| 4988 * | 4814 * |
| 4989 * @param node the constructor declaration to evaluate | |
| 4990 * @param constructorElement the constructor element | |
| 4991 * @return `true` if and only if an error code is generated on the passed node | |
| 4992 * See [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]. | 4815 * See [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]. |
| 4993 */ | 4816 */ |
| 4994 bool _checkForRedirectToNonConstConstructor( | 4817 bool _checkForRedirectToNonConstConstructor( |
| 4995 ConstructorDeclaration node, ConstructorElement constructorElement) { | 4818 ConstructorDeclaration node, ConstructorElement constructorElement) { |
| 4996 // prepare redirected constructor | 4819 // prepare redirected constructor |
| 4997 ConstructorName redirectedConstructorNode = node.redirectedConstructor; | 4820 ConstructorName redirectedConstructorNode = node.redirectedConstructor; |
| 4998 if (redirectedConstructorNode == null) { | 4821 if (redirectedConstructorNode == null) { |
| 4999 return false; | 4822 return false; |
| 5000 } | 4823 } |
| 5001 // prepare element | 4824 // prepare element |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5017 return false; | 4840 return false; |
| 5018 } | 4841 } |
| 5019 // report error | 4842 // report error |
| 5020 _errorReporter.reportErrorForNode( | 4843 _errorReporter.reportErrorForNode( |
| 5021 CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, | 4844 CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, |
| 5022 redirectedConstructorNode); | 4845 redirectedConstructorNode); |
| 5023 return true; | 4846 return true; |
| 5024 } | 4847 } |
| 5025 | 4848 |
| 5026 /** | 4849 /** |
| 5027 * This checks that the rethrow is inside of a catch clause. | 4850 * Check that the given rethrow [expression] is inside of a catch clause. |
| 5028 * | 4851 * |
| 5029 * @param node the rethrow expression to evaluate | |
| 5030 * @return `true` if and only if an error code is generated on the passed node | |
| 5031 * See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]. | 4852 * See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]. |
| 5032 */ | 4853 */ |
| 5033 bool _checkForRethrowOutsideCatch(RethrowExpression node) { | 4854 bool _checkForRethrowOutsideCatch(RethrowExpression node) { |
| 5034 if (!_isInCatchClause) { | 4855 if (!_isInCatchClause) { |
| 5035 _errorReporter.reportErrorForNode( | 4856 _errorReporter.reportErrorForNode( |
| 5036 CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, node); | 4857 CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, node); |
| 5037 return true; | 4858 return true; |
| 5038 } | 4859 } |
| 5039 return false; | 4860 return false; |
| 5040 } | 4861 } |
| 5041 | 4862 |
| 5042 /** | 4863 /** |
| 5043 * This checks that if the the given constructor declaration is generative, th
en it does not have | 4864 * Check that if the the given constructor [declaration] is generative, then |
| 5044 * an expression function body. | 4865 * it does not have an expression function body. |
| 5045 * | 4866 * |
| 5046 * @param node the constructor to evaluate | |
| 5047 * @return `true` if and only if an error code is generated on the passed node | |
| 5048 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]. | 4867 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]. |
| 5049 */ | 4868 */ |
| 5050 bool _checkForReturnInGenerativeConstructor(ConstructorDeclaration node) { | 4869 bool _checkForReturnInGenerativeConstructor(ConstructorDeclaration node) { |
| 5051 // ignore factory | 4870 // ignore factory |
| 5052 if (node.factoryKeyword != null) { | 4871 if (node.factoryKeyword != null) { |
| 5053 return false; | 4872 return false; |
| 5054 } | 4873 } |
| 5055 // block body (with possible return statement) is checked elsewhere | 4874 // block body (with possible return statement) is checked elsewhere |
| 5056 FunctionBody body = node.body; | 4875 FunctionBody body = node.body; |
| 5057 if (body is! ExpressionFunctionBody) { | 4876 if (body is! ExpressionFunctionBody) { |
| 5058 return false; | 4877 return false; |
| 5059 } | 4878 } |
| 5060 // report error | 4879 // report error |
| 5061 _errorReporter.reportErrorForNode( | 4880 _errorReporter.reportErrorForNode( |
| 5062 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body); | 4881 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body); |
| 5063 return true; | 4882 return true; |
| 5064 } | 4883 } |
| 5065 | 4884 |
| 5066 /** | 4885 /** |
| 5067 * This checks that a type mis-match between the return type and the expressed
return type by the | 4886 * Check that a type mis-match between the type of the [returnExpression] and |
| 5068 * enclosing method or function. | 4887 * the [expectedReturnType] by the enclosing method or function. |
| 5069 * | 4888 * |
| 5070 * This method is called both by [checkForAllReturnStatementErrorCodes] | 4889 * This method is called both by [_checkForAllReturnStatementErrorCodes] |
| 5071 * and [visitExpressionFunctionBody]. | 4890 * and [visitExpressionFunctionBody]. |
| 5072 * | 4891 * |
| 5073 * @param returnExpression the returned expression to evaluate | |
| 5074 * @param expectedReturnType the expressed return type by the enclosing method
or function | |
| 5075 * @return `true` if and only if an error code is generated on the passed node | |
| 5076 * See [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. | 4892 * See [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. |
| 5077 */ | 4893 */ |
| 5078 bool _checkForReturnOfInvalidType( | 4894 bool _checkForReturnOfInvalidType( |
| 5079 Expression returnExpression, DartType expectedReturnType) { | 4895 Expression returnExpression, DartType expectedReturnType) { |
| 5080 if (_enclosingFunction == null) { | 4896 if (_enclosingFunction == null) { |
| 5081 return false; | 4897 return false; |
| 5082 } | 4898 } |
| 5083 if (_inGenerator) { | 4899 if (_inGenerator) { |
| 5084 // "return expression;" is disallowed in generators, but this is checked | 4900 // "return expression;" is disallowed in generators, but this is checked |
| 5085 // elsewhere. Bare "return" is always allowed in generators regardless | 4901 // elsewhere. Bare "return" is always allowed in generators regardless |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5121 // errorReporter.reportTypeErrorForNode( | 4937 // errorReporter.reportTypeErrorForNode( |
| 5122 // StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, | 4938 // StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, |
| 5123 // returnExpression, | 4939 // returnExpression, |
| 5124 // staticReturnType, | 4940 // staticReturnType, |
| 5125 // expectedReturnType, | 4941 // expectedReturnType, |
| 5126 // enclosingFunction.getDisplayName()); | 4942 // enclosingFunction.getDisplayName()); |
| 5127 // return true; | 4943 // return true; |
| 5128 } | 4944 } |
| 5129 | 4945 |
| 5130 /** | 4946 /** |
| 5131 * This checks the given "typeReference" and that the "name" is not the refere
nce to an instance | 4947 * Check the given [typeReference] and that the [name] is not the reference to |
| 5132 * member. | 4948 * an instance member. |
| 5133 * | 4949 * |
| 5134 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, | |
| 5135 * or `null`, aka, the class element of 'C' in 'C.x', see | |
| 5136 * [getTypeReference] | |
| 5137 * @param name the accessed name to evaluate | |
| 5138 * @return `true` if and only if an error code is generated on the passed node | |
| 5139 * See [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]. | 4950 * See [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]. |
| 5140 */ | 4951 */ |
| 5141 bool _checkForStaticAccessToInstanceMember( | 4952 bool _checkForStaticAccessToInstanceMember( |
| 5142 ClassElement typeReference, SimpleIdentifier name) { | 4953 ClassElement typeReference, SimpleIdentifier name) { |
| 5143 // OK, target is not a type | 4954 // OK, target is not a type |
| 5144 if (typeReference == null) { | 4955 if (typeReference == null) { |
| 5145 return false; | 4956 return false; |
| 5146 } | 4957 } |
| 5147 // prepare member Element | 4958 // prepare member Element |
| 5148 Element element = name.staticElement; | 4959 Element element = name.staticElement; |
| 5149 if (element is! ExecutableElement) { | 4960 if (element is! ExecutableElement) { |
| 5150 return false; | 4961 return false; |
| 5151 } | 4962 } |
| 5152 ExecutableElement memberElement = element as ExecutableElement; | 4963 ExecutableElement memberElement = element as ExecutableElement; |
| 5153 // OK, static | 4964 // OK, static |
| 5154 if (memberElement.isStatic) { | 4965 if (memberElement.isStatic) { |
| 5155 return false; | 4966 return false; |
| 5156 } | 4967 } |
| 5157 // report problem | 4968 // report problem |
| 5158 _errorReporter.reportErrorForNode( | 4969 _errorReporter.reportErrorForNode( |
| 5159 StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]); | 4970 StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]); |
| 5160 return true; | 4971 return true; |
| 5161 } | 4972 } |
| 5162 | 4973 |
| 5163 /** | 4974 /** |
| 5164 * This checks that the type of the passed 'switch' expression is assignable t
o the type of the | 4975 * Check that the type of the expression in the given 'switch' [statement] is |
| 5165 * 'case' members. | 4976 * assignable to the type of the 'case' members. |
| 5166 * | 4977 * |
| 5167 * @param node the 'switch' statement to evaluate | |
| 5168 * @return `true` if and only if an error code is generated on the passed node | |
| 5169 * See [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE]. | 4978 * See [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE]. |
| 5170 */ | 4979 */ |
| 5171 bool _checkForSwitchExpressionNotAssignable(SwitchStatement node) { | 4980 bool _checkForSwitchExpressionNotAssignable(SwitchStatement node) { |
| 5172 // prepare 'switch' expression type | 4981 // prepare 'switch' expression type |
| 5173 Expression expression = node.expression; | 4982 Expression expression = node.expression; |
| 5174 DartType expressionType = getStaticType(expression); | 4983 DartType expressionType = getStaticType(expression); |
| 5175 if (expressionType == null) { | 4984 if (expressionType == null) { |
| 5176 return false; | 4985 return false; |
| 5177 } | 4986 } |
| 5178 // compare with type of the first 'case' | 4987 // compare with type of the first 'case' |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5194 StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE, expression, [ | 5003 StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE, expression, [ |
| 5195 expressionType, | 5004 expressionType, |
| 5196 caseType | 5005 caseType |
| 5197 ]); | 5006 ]); |
| 5198 return true; | 5007 return true; |
| 5199 } | 5008 } |
| 5200 return false; | 5009 return false; |
| 5201 } | 5010 } |
| 5202 | 5011 |
| 5203 /** | 5012 /** |
| 5204 * This verifies that the passed function type alias does not reference itself
directly. | 5013 * Verify that the given function type [alias] does not reference itself |
| 5014 * directly. |
| 5205 * | 5015 * |
| 5206 * @param node the function type alias to evaluate | |
| 5207 * @return `true` if and only if an error code is generated on the passed node | |
| 5208 * See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]. | 5016 * See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]. |
| 5209 */ | 5017 */ |
| 5210 bool _checkForTypeAliasCannotReferenceItself_function( | 5018 bool _checkForTypeAliasCannotReferenceItself_function( |
| 5211 FunctionTypeAlias node) { | 5019 FunctionTypeAlias node) { |
| 5212 FunctionTypeAliasElement element = node.element; | 5020 FunctionTypeAliasElement element = node.element; |
| 5213 if (!_hasTypedefSelfReference(element)) { | 5021 if (!_hasTypedefSelfReference(element)) { |
| 5214 return false; | 5022 return false; |
| 5215 } | 5023 } |
| 5216 _errorReporter.reportErrorForNode( | 5024 _errorReporter.reportErrorForNode( |
| 5217 CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, node); | 5025 CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, node); |
| 5218 return true; | 5026 return true; |
| 5219 } | 5027 } |
| 5220 | 5028 |
| 5221 /** | 5029 /** |
| 5222 * This verifies that the passed type name is not a deferred type. | 5030 * Verify that the given type [name] is not a deferred type. |
| 5223 * | 5031 * |
| 5224 * @param expression the expression to evaluate | |
| 5225 * @return `true` if and only if an error code is generated on the passed node | |
| 5226 * See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS]. | 5032 * See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS]. |
| 5227 */ | 5033 */ |
| 5228 bool _checkForTypeAnnotationDeferredClass(TypeName node) { | 5034 bool _checkForTypeAnnotationDeferredClass(TypeName node) { |
| 5229 if (node != null && node.isDeferred) { | 5035 if (node != null && node.isDeferred) { |
| 5230 _errorReporter.reportErrorForNode( | 5036 _errorReporter.reportErrorForNode( |
| 5231 StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, node, [node.name]); | 5037 StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, node, [node.name]); |
| 5232 } | 5038 } |
| 5233 return false; | 5039 return false; |
| 5234 } | 5040 } |
| 5235 | 5041 |
| 5236 /** | 5042 /** |
| 5237 * This verifies that the type arguments in the passed type name are all withi
n their bounds. | 5043 * Verify that the type arguments in the given type [name] are all within |
| 5044 * their bounds. |
| 5238 * | 5045 * |
| 5239 * @param node the [TypeName] to evaluate | |
| 5240 * @return `true` if and only if an error code is generated on the passed node | |
| 5241 * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]. | 5046 * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]. |
| 5242 */ | 5047 */ |
| 5243 bool _checkForTypeArgumentNotMatchingBounds(TypeName node) { | 5048 bool _checkForTypeArgumentNotMatchingBounds(TypeName node) { |
| 5244 if (node.typeArguments == null) { | 5049 if (node.typeArguments == null) { |
| 5245 return false; | 5050 return false; |
| 5246 } | 5051 } |
| 5247 // prepare Type | 5052 // prepare Type |
| 5248 DartType type = node.type; | 5053 DartType type = node.type; |
| 5249 if (type == null) { | 5054 if (type == null) { |
| 5250 return false; | 5055 return false; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5283 _errorReporter.reportTypeErrorForNode( | 5088 _errorReporter.reportTypeErrorForNode( |
| 5284 errorCode, argTypeName, [argType, boundType]); | 5089 errorCode, argTypeName, [argType, boundType]); |
| 5285 foundError = true; | 5090 foundError = true; |
| 5286 } | 5091 } |
| 5287 } | 5092 } |
| 5288 } | 5093 } |
| 5289 return foundError; | 5094 return foundError; |
| 5290 } | 5095 } |
| 5291 | 5096 |
| 5292 /** | 5097 /** |
| 5293 * This checks that if the passed type name is a type parameter being used to
define a static | 5098 * Check whether the given type [name] is a type parameter being used to |
| 5294 * member. | 5099 * define a static member. |
| 5295 * | 5100 * |
| 5296 * @param node the type name to evaluate | |
| 5297 * @return `true` if and only if an error code is generated on the passed node | |
| 5298 * See [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]. | 5101 * See [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]. |
| 5299 */ | 5102 */ |
| 5300 bool _checkForTypeParameterReferencedByStatic(TypeName node) { | 5103 bool _checkForTypeParameterReferencedByStatic(TypeName node) { |
| 5301 if (_isInStaticMethod || _isInStaticVariableDeclaration) { | 5104 if (_isInStaticMethod || _isInStaticVariableDeclaration) { |
| 5302 DartType type = node.type; | 5105 DartType type = node.type; |
| 5303 if (type is TypeParameterType) { | 5106 if (type is TypeParameterType) { |
| 5304 _errorReporter.reportErrorForNode( | 5107 _errorReporter.reportErrorForNode( |
| 5305 StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, node); | 5108 StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, node); |
| 5306 return true; | 5109 return true; |
| 5307 } | 5110 } |
| 5308 } | 5111 } |
| 5309 return false; | 5112 return false; |
| 5310 } | 5113 } |
| 5311 | 5114 |
| 5312 /** | 5115 /** |
| 5313 * This checks that if the passed type parameter is a supertype of its bound. | 5116 * Check whether the given type [parameter] is a supertype of its bound. |
| 5314 * | 5117 * |
| 5315 * @param node the type parameter to evaluate | |
| 5316 * @return `true` if and only if an error code is generated on the passed node | |
| 5317 * See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND]. | 5118 * See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND]. |
| 5318 */ | 5119 */ |
| 5319 bool _checkForTypeParameterSupertypeOfItsBound(TypeParameter node) { | 5120 bool _checkForTypeParameterSupertypeOfItsBound(TypeParameter node) { |
| 5320 TypeParameterElement element = node.element; | 5121 TypeParameterElement element = node.element; |
| 5321 // prepare bound | 5122 // prepare bound |
| 5322 DartType bound = element.bound; | 5123 DartType bound = element.bound; |
| 5323 if (bound == null) { | 5124 if (bound == null) { |
| 5324 return false; | 5125 return false; |
| 5325 } | 5126 } |
| 5326 // OK, type parameter is not supertype of its bound | 5127 // OK, type parameter is not supertype of its bound |
| 5327 if (!bound.isMoreSpecificThan(element.type)) { | 5128 if (!bound.isMoreSpecificThan(element.type)) { |
| 5328 return false; | 5129 return false; |
| 5329 } | 5130 } |
| 5330 // report problem | 5131 // report problem |
| 5331 _errorReporter.reportErrorForNode( | 5132 _errorReporter.reportErrorForNode( |
| 5332 StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, node, | 5133 StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, node, |
| 5333 [element.displayName]); | 5134 [element.displayName]); |
| 5334 return true; | 5135 return true; |
| 5335 } | 5136 } |
| 5336 | 5137 |
| 5337 /** | 5138 /** |
| 5338 * This checks that if the passed generative constructor has neither an explic
it super constructor | 5139 * Check that if the given generative [constructor] has neither an explicit |
| 5339 * invocation nor a redirecting constructor invocation, that the superclass ha
s a default | 5140 * super constructor invocation nor a redirecting constructor invocation, that |
| 5340 * generative constructor. | 5141 * the superclass has a default generative constructor. |
| 5341 * | 5142 * |
| 5342 * @param node the constructor declaration to evaluate | |
| 5343 * @return `true` if and only if an error code is generated on the passed node | |
| 5344 * See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT], | 5143 * See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT], |
| 5345 * [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and | 5144 * [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and |
| 5346 * [StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]. | 5145 * [StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]. |
| 5347 */ | 5146 */ |
| 5348 bool _checkForUndefinedConstructorInInitializerImplicit( | 5147 bool _checkForUndefinedConstructorInInitializerImplicit( |
| 5349 ConstructorDeclaration node) { | 5148 ConstructorDeclaration node) { |
| 5350 if (_enclosingClass == null) { | 5149 if (_enclosingClass == null) { |
| 5351 return false; | 5150 return false; |
| 5352 } | 5151 } |
| 5353 // do nothing if mixin errors have already been reported for this class. | 5152 // do nothing if mixin errors have already been reported for this class. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5406 } | 5205 } |
| 5407 return false; | 5206 return false; |
| 5408 } | 5207 } |
| 5409 _errorReporter.reportErrorForNode( | 5208 _errorReporter.reportErrorForNode( |
| 5410 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, | 5209 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, |
| 5411 node.returnType, [superElement.name]); | 5210 node.returnType, [superElement.name]); |
| 5412 return true; | 5211 return true; |
| 5413 } | 5212 } |
| 5414 | 5213 |
| 5415 /** | 5214 /** |
| 5416 * This checks that if the given name is a reference to a static member it is
defined in the | 5215 * Check that if the given [name] is a reference to a static member it is |
| 5417 * enclosing class rather than in a superclass. | 5216 * defined in the enclosing class rather than in a superclass. |
| 5418 * | 5217 * |
| 5419 * @param name the name to be evaluated | |
| 5420 * @return `true` if and only if an error code is generated on the passed node | |
| 5421 * See [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER
]. | 5218 * See [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER
]. |
| 5422 */ | 5219 */ |
| 5423 bool _checkForUnqualifiedReferenceToNonLocalStaticMember( | 5220 bool _checkForUnqualifiedReferenceToNonLocalStaticMember( |
| 5424 SimpleIdentifier name) { | 5221 SimpleIdentifier name) { |
| 5425 Element element = name.staticElement; | 5222 Element element = name.staticElement; |
| 5426 if (element == null || element is TypeParameterElement) { | 5223 if (element == null || element is TypeParameterElement) { |
| 5427 return false; | 5224 return false; |
| 5428 } | 5225 } |
| 5429 Element enclosingElement = element.enclosingElement; | 5226 Element enclosingElement = element.enclosingElement; |
| 5430 if (enclosingElement is! ClassElement) { | 5227 if (enclosingElement is! ClassElement) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5485 } | 5282 } |
| 5486 } | 5283 } |
| 5487 } | 5284 } |
| 5488 // else { | 5285 // else { |
| 5489 // // TODO(jwren) Report error, constructor initializer variable is a top
level element | 5286 // // TODO(jwren) Report error, constructor initializer variable is a top
level element |
| 5490 // // (Either here or in ErrorVerifier.checkForAllFinalInitializedErrorCo
des) | 5287 // // (Either here or in ErrorVerifier.checkForAllFinalInitializedErrorCo
des) |
| 5491 // } | 5288 // } |
| 5492 } | 5289 } |
| 5493 | 5290 |
| 5494 /** | 5291 /** |
| 5495 * This verifies that the given getter does not have a return type of 'void'. | 5292 * Verify that the given [getter] does not have a return type of 'void'. |
| 5496 * | 5293 * |
| 5497 * @param node the method declaration to evaluate | |
| 5498 * @return `true` if and only if an error code is generated on the passed node | |
| 5499 * See [StaticWarningCode.VOID_RETURN_FOR_GETTER]. | 5294 * See [StaticWarningCode.VOID_RETURN_FOR_GETTER]. |
| 5500 */ | 5295 */ |
| 5501 bool _checkForVoidReturnType(MethodDeclaration node) { | 5296 bool _checkForVoidReturnType(MethodDeclaration node) { |
| 5502 TypeName returnType = node.returnType; | 5297 TypeName returnType = node.returnType; |
| 5503 if (returnType == null || returnType.name.name != "void") { | 5298 if (returnType == null || returnType.name.name != "void") { |
| 5504 return false; | 5299 return false; |
| 5505 } | 5300 } |
| 5506 _errorReporter.reportErrorForNode( | 5301 _errorReporter.reportErrorForNode( |
| 5507 StaticWarningCode.VOID_RETURN_FOR_GETTER, returnType); | 5302 StaticWarningCode.VOID_RETURN_FOR_GETTER, returnType); |
| 5508 return true; | 5303 return true; |
| 5509 } | 5304 } |
| 5510 | 5305 |
| 5511 /** | 5306 /** |
| 5512 * This verifies the passed operator-method declaration, has correct number of
parameters. | 5307 * Verify the given operator-method [declaration], has correct number of |
| 5308 * parameters. |
| 5513 * | 5309 * |
| 5514 * This method assumes that the method declaration was tested to be an operato
r declaration before | 5310 * This method assumes that the method declaration was tested to be an |
| 5515 * being called. | 5311 * operator declaration before being called. |
| 5516 * | 5312 * |
| 5517 * @param node the method declaration to evaluate | |
| 5518 * @return `true` if and only if an error code is generated on the passed node | |
| 5519 * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR]. | 5313 * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR]. |
| 5520 */ | 5314 */ |
| 5521 bool _checkForWrongNumberOfParametersForOperator(MethodDeclaration node) { | 5315 bool _checkForWrongNumberOfParametersForOperator(MethodDeclaration node) { |
| 5522 // prepare number of parameters | 5316 // prepare number of parameters |
| 5523 FormalParameterList parameterList = node.parameters; | 5317 FormalParameterList parameterList = node.parameters; |
| 5524 if (parameterList == null) { | 5318 if (parameterList == null) { |
| 5525 return false; | 5319 return false; |
| 5526 } | 5320 } |
| 5527 int numParameters = parameterList.parameters.length; | 5321 int numParameters = parameterList.parameters.length; |
| 5528 // prepare operator name | 5322 // prepare operator name |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5566 _errorReporter.reportErrorForNode( | 5360 _errorReporter.reportErrorForNode( |
| 5567 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS, | 5361 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS, |
| 5568 nameNode, [numParameters]); | 5362 nameNode, [numParameters]); |
| 5569 return true; | 5363 return true; |
| 5570 } | 5364 } |
| 5571 // OK | 5365 // OK |
| 5572 return false; | 5366 return false; |
| 5573 } | 5367 } |
| 5574 | 5368 |
| 5575 /** | 5369 /** |
| 5576 * This verifies if the passed setter parameter list have only one required pa
rameter. | 5370 * Verify that the given setter [parameterList] has only one required |
| 5371 * parameter. The [setterName] is the name of the setter to report problems |
| 5372 * on. |
| 5577 * | 5373 * |
| 5578 * This method assumes that the method declaration was tested to be a setter b
efore being called. | 5374 * This method assumes that the method declaration was tested to be a setter |
| 5375 * before being called. |
| 5579 * | 5376 * |
| 5580 * @param setterName the name of the setter to report problems on | |
| 5581 * @param parameterList the parameter list to evaluate | |
| 5582 * @return `true` if and only if an error code is generated on the passed node | |
| 5583 * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]. | 5377 * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]. |
| 5584 */ | 5378 */ |
| 5585 bool _checkForWrongNumberOfParametersForSetter( | 5379 bool _checkForWrongNumberOfParametersForSetter( |
| 5586 SimpleIdentifier setterName, FormalParameterList parameterList) { | 5380 SimpleIdentifier setterName, FormalParameterList parameterList) { |
| 5587 if (setterName == null) { | 5381 if (setterName == null) { |
| 5588 return false; | 5382 return false; |
| 5589 } | 5383 } |
| 5590 if (parameterList == null) { | 5384 if (parameterList == null) { |
| 5591 return false; | 5385 return false; |
| 5592 } | 5386 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5649 impliedReturnType, | 5443 impliedReturnType, |
| 5650 requiredReturnType | 5444 requiredReturnType |
| 5651 ]); | 5445 ]); |
| 5652 return true; | 5446 return true; |
| 5653 } | 5447 } |
| 5654 } | 5448 } |
| 5655 return false; | 5449 return false; |
| 5656 } | 5450 } |
| 5657 | 5451 |
| 5658 /** | 5452 /** |
| 5659 * This verifies that if the given class declaration implements the class Func
tion that it has a | 5453 * Verify that if the given class [declaration] implements the class Function |
| 5660 * concrete implementation of the call method. | 5454 * that it has a concrete implementation of the call method. |
| 5661 * | 5455 * |
| 5662 * @return `true` if and only if an error code is generated on the passed node | |
| 5663 * See [StaticWarningCode.FUNCTION_WITHOUT_CALL]. | 5456 * See [StaticWarningCode.FUNCTION_WITHOUT_CALL]. |
| 5664 */ | 5457 */ |
| 5665 bool _checkImplementsFunctionWithoutCall(ClassDeclaration node) { | 5458 bool _checkImplementsFunctionWithoutCall(ClassDeclaration node) { |
| 5666 if (node.isAbstract) { | 5459 if (node.isAbstract) { |
| 5667 return false; | 5460 return false; |
| 5668 } | 5461 } |
| 5669 ClassElement classElement = node.element; | 5462 ClassElement classElement = node.element; |
| 5670 if (classElement == null) { | 5463 if (classElement == null) { |
| 5671 return false; | 5464 return false; |
| 5672 } | 5465 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5685 callMethod is! MethodElement || | 5478 callMethod is! MethodElement || |
| 5686 (callMethod as MethodElement).isAbstract) { | 5479 (callMethod as MethodElement).isAbstract) { |
| 5687 _errorReporter.reportErrorForNode( | 5480 _errorReporter.reportErrorForNode( |
| 5688 StaticWarningCode.FUNCTION_WITHOUT_CALL, node.name); | 5481 StaticWarningCode.FUNCTION_WITHOUT_CALL, node.name); |
| 5689 return true; | 5482 return true; |
| 5690 } | 5483 } |
| 5691 return false; | 5484 return false; |
| 5692 } | 5485 } |
| 5693 | 5486 |
| 5694 /** | 5487 /** |
| 5695 * This verifies that the given class declaration does not have the same class
in the 'extends' | 5488 * Verify that the given class [declaration] does not have the same class in |
| 5696 * and 'implements' clauses. | 5489 * the 'extends' and 'implements' clauses. |
| 5697 * | 5490 * |
| 5698 * @return `true` if and only if an error code is generated on the passed node | |
| 5699 * See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]. | 5491 * See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]. |
| 5700 */ | 5492 */ |
| 5701 bool _checkImplementsSuperClass(ClassDeclaration node) { | 5493 bool _checkImplementsSuperClass(ClassDeclaration node) { |
| 5702 // prepare super type | 5494 // prepare super type |
| 5703 InterfaceType superType = _enclosingClass.supertype; | 5495 InterfaceType superType = _enclosingClass.supertype; |
| 5704 if (superType == null) { | 5496 if (superType == null) { |
| 5705 return false; | 5497 return false; |
| 5706 } | 5498 } |
| 5707 // prepare interfaces | 5499 // prepare interfaces |
| 5708 ImplementsClause implementsClause = node.implementsClause; | 5500 ImplementsClause implementsClause = node.implementsClause; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 5737 DartType staticReturnType = getStaticType(returnExpression); | 5529 DartType staticReturnType = getStaticType(returnExpression); |
| 5738 if (staticReturnType != null && _enclosingFunction.isAsynchronous) { | 5530 if (staticReturnType != null && _enclosingFunction.isAsynchronous) { |
| 5739 return _typeProvider.futureType.substitute4(<DartType>[ | 5531 return _typeProvider.futureType.substitute4(<DartType>[ |
| 5740 StaticTypeAnalyzer.flattenFutures(_typeProvider, staticReturnType) | 5532 StaticTypeAnalyzer.flattenFutures(_typeProvider, staticReturnType) |
| 5741 ]); | 5533 ]); |
| 5742 } | 5534 } |
| 5743 return staticReturnType; | 5535 return staticReturnType; |
| 5744 } | 5536 } |
| 5745 | 5537 |
| 5746 /** | 5538 /** |
| 5747 * Return the error code that should be used when the given class references i
tself directly. | 5539 * Return the error code that should be used when the given class [element] |
| 5748 * | 5540 * references itself directly. |
| 5749 * @param classElt the class that references itself | |
| 5750 * @return the error code that should be used | |
| 5751 */ | 5541 */ |
| 5752 ErrorCode _getBaseCaseErrorCode(ClassElement classElt) { | 5542 ErrorCode _getBaseCaseErrorCode(ClassElement classElt) { |
| 5753 InterfaceType supertype = classElt.supertype; | 5543 InterfaceType supertype = classElt.supertype; |
| 5754 if (supertype != null && _enclosingClass == supertype.element) { | 5544 if (supertype != null && _enclosingClass == supertype.element) { |
| 5755 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTE
NDS; | 5545 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTE
NDS; |
| 5756 } | 5546 } |
| 5757 List<InterfaceType> mixins = classElt.mixins; | 5547 List<InterfaceType> mixins = classElt.mixins; |
| 5758 for (int i = 0; i < mixins.length; i++) { | 5548 for (int i = 0; i < mixins.length; i++) { |
| 5759 if (_enclosingClass == mixins[i].element) { | 5549 if (_enclosingClass == mixins[i].element) { |
| 5760 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WI
TH; | 5550 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WI
TH; |
| 5761 } | 5551 } |
| 5762 } | 5552 } |
| 5763 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEM
ENTS; | 5553 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEM
ENTS; |
| 5764 } | 5554 } |
| 5765 | 5555 |
| 5766 /** | 5556 /** |
| 5767 * Given an expression in a switch case whose value is expected to be an enum
constant, return the | 5557 * Given an [expression] in a switch case whose value is expected to be an |
| 5768 * name of the constant. | 5558 * enum constant, return the name of the constant. |
| 5769 * | |
| 5770 * @param expression the expression from the switch case | |
| 5771 * @return the name of the constant referenced by the expression | |
| 5772 */ | 5559 */ |
| 5773 String _getConstantName(Expression expression) { | 5560 String _getConstantName(Expression expression) { |
| 5774 // TODO(brianwilkerson) Convert this to return the element representing the | 5561 // TODO(brianwilkerson) Convert this to return the element representing the |
| 5775 // constant. | 5562 // constant. |
| 5776 if (expression is SimpleIdentifier) { | 5563 if (expression is SimpleIdentifier) { |
| 5777 return expression.name; | 5564 return expression.name; |
| 5778 } else if (expression is PrefixedIdentifier) { | 5565 } else if (expression is PrefixedIdentifier) { |
| 5779 return expression.identifier.name; | 5566 return expression.identifier.name; |
| 5780 } else if (expression is PropertyAccess) { | 5567 } else if (expression is PropertyAccess) { |
| 5781 return expression.propertyName.name; | 5568 return expression.propertyName.name; |
| 5782 } | 5569 } |
| 5783 return null; | 5570 return null; |
| 5784 } | 5571 } |
| 5785 | 5572 |
| 5786 /** | 5573 /** |
| 5787 * Returns the Type (return type) for a given getter. | 5574 * Return the return type of the given [getter]. |
| 5788 * | |
| 5789 * @param propertyAccessorElement | |
| 5790 * @return The type of the given getter. | |
| 5791 */ | 5575 */ |
| 5792 DartType _getGetterType(PropertyAccessorElement propertyAccessorElement) { | 5576 DartType _getGetterType(PropertyAccessorElement propertyAccessorElement) { |
| 5793 FunctionType functionType = propertyAccessorElement.type; | 5577 FunctionType functionType = propertyAccessorElement.type; |
| 5794 if (functionType != null) { | 5578 if (functionType != null) { |
| 5795 return functionType.returnType; | 5579 return functionType.returnType; |
| 5796 } else { | 5580 } else { |
| 5797 return null; | 5581 return null; |
| 5798 } | 5582 } |
| 5799 } | 5583 } |
| 5800 | 5584 |
| 5801 /** | 5585 /** |
| 5802 * Returns the Type (first and only parameter) for a given setter. | 5586 * Return the type of the first and only parameter of the given [setter]. |
| 5803 * | |
| 5804 * @param propertyAccessorElement | |
| 5805 * @return The type of the given setter. | |
| 5806 */ | 5587 */ |
| 5807 DartType _getSetterType(PropertyAccessorElement propertyAccessorElement) { | 5588 DartType _getSetterType(PropertyAccessorElement propertyAccessorElement) { |
| 5808 // Get the parameters for MethodDeclaration or FunctionDeclaration | 5589 // Get the parameters for MethodDeclaration or FunctionDeclaration |
| 5809 List<ParameterElement> setterParameters = | 5590 List<ParameterElement> setterParameters = |
| 5810 propertyAccessorElement.parameters; | 5591 propertyAccessorElement.parameters; |
| 5811 // If there are no setter parameters, return no type. | 5592 // If there are no setter parameters, return no type. |
| 5812 if (setterParameters.length == 0) { | 5593 if (setterParameters.length == 0) { |
| 5813 return null; | 5594 return null; |
| 5814 } | 5595 } |
| 5815 return setterParameters[0].type; | 5596 return setterParameters[0].type; |
| 5816 } | 5597 } |
| 5817 | 5598 |
| 5818 /** | 5599 /** |
| 5819 * Given a list of directives that have the same prefix, generate an error if
there is more than | 5600 * Given a list of [directives] that have the same prefix, generate an error |
| 5820 * one import and any of those imports is deferred. | 5601 * if there is more than one import and any of those imports is deferred. |
| 5821 * | 5602 * |
| 5822 * @param directives the list of directives that have the same prefix | |
| 5823 * @return `true` if an error was generated | |
| 5824 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. | 5603 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. |
| 5825 */ | 5604 */ |
| 5826 bool _hasDeferredPrefixCollision(List<ImportDirective> directives) { | 5605 bool _hasDeferredPrefixCollision(List<ImportDirective> directives) { |
| 5827 bool foundError = false; | 5606 bool foundError = false; |
| 5828 int count = directives.length; | 5607 int count = directives.length; |
| 5829 if (count > 1) { | 5608 if (count > 1) { |
| 5830 for (int i = 0; i < count; i++) { | 5609 for (int i = 0; i < count; i++) { |
| 5831 sc.Token deferredToken = directives[i].deferredKeyword; | 5610 sc.Token deferredToken = directives[i].deferredKeyword; |
| 5832 if (deferredToken != null) { | 5611 if (deferredToken != null) { |
| 5833 _errorReporter.reportErrorForToken( | 5612 _errorReporter.reportErrorForToken( |
| 5834 CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken); | 5613 CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken); |
| 5835 foundError = true; | 5614 foundError = true; |
| 5836 } | 5615 } |
| 5837 } | 5616 } |
| 5838 } | 5617 } |
| 5839 return foundError; | 5618 return foundError; |
| 5840 } | 5619 } |
| 5841 | 5620 |
| 5842 /** | 5621 /** |
| 5843 * @return `true` if the given constructor redirects to itself, directly or in
directly | 5622 * Return `true` if the given [constructor] redirects to itself, directly or |
| 5623 * indirectly. |
| 5844 */ | 5624 */ |
| 5845 bool _hasRedirectingFactoryConstructorCycle(ConstructorElement element) { | 5625 bool _hasRedirectingFactoryConstructorCycle(ConstructorElement element) { |
| 5846 Set<ConstructorElement> constructors = new HashSet<ConstructorElement>(); | 5626 Set<ConstructorElement> constructors = new HashSet<ConstructorElement>(); |
| 5847 ConstructorElement current = element; | 5627 ConstructorElement current = element; |
| 5848 while (current != null) { | 5628 while (current != null) { |
| 5849 if (constructors.contains(current)) { | 5629 if (constructors.contains(current)) { |
| 5850 return identical(current, element); | 5630 return identical(current, element); |
| 5851 } | 5631 } |
| 5852 constructors.add(current); | 5632 constructors.add(current); |
| 5853 current = current.redirectedConstructor; | 5633 current = current.redirectedConstructor; |
| 5854 if (current is ConstructorMember) { | 5634 if (current is ConstructorMember) { |
| 5855 current = (current as ConstructorMember).baseElement; | 5635 current = (current as ConstructorMember).baseElement; |
| 5856 } | 5636 } |
| 5857 } | 5637 } |
| 5858 return false; | 5638 return false; |
| 5859 } | 5639 } |
| 5860 | 5640 |
| 5861 /** | 5641 /** |
| 5862 * @return <code>true</code> if given [Element] has direct or indirect referen
ce to itself | 5642 * Return `true` if the given [element] has direct or indirect reference to |
| 5863 * from anywhere except [ClassElement] or type parameter bounds. | 5643 * itself from anywhere except a class element or type parameter bounds. |
| 5864 */ | 5644 */ |
| 5865 bool _hasTypedefSelfReference(Element target) { | 5645 bool _hasTypedefSelfReference(Element target) { |
| 5866 Set<Element> checked = new HashSet<Element>(); | 5646 Set<Element> checked = new HashSet<Element>(); |
| 5867 List<Element> toCheck = new List<Element>(); | 5647 List<Element> toCheck = new List<Element>(); |
| 5868 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference elementVisi
tor = | 5648 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference elementVisi
tor = |
| 5869 new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference( | 5649 new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference( |
| 5870 toCheck); | 5650 toCheck); |
| 5871 toCheck.add(target); | 5651 toCheck.add(target); |
| 5872 bool firstIteration = true; | 5652 bool firstIteration = true; |
| 5873 while (true) { | 5653 while (true) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5905 return true; | 5685 return true; |
| 5906 } else if (type is InterfaceType) { | 5686 } else if (type is InterfaceType) { |
| 5907 MethodElement callMethod = | 5687 MethodElement callMethod = |
| 5908 type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _currentLibrary); | 5688 type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _currentLibrary); |
| 5909 return callMethod != null; | 5689 return callMethod != null; |
| 5910 } | 5690 } |
| 5911 return false; | 5691 return false; |
| 5912 } | 5692 } |
| 5913 | 5693 |
| 5914 /** | 5694 /** |
| 5915 * Return `true` iff the passed [ClassElement] has a method, getter or setter
that | 5695 * Return `true` iff the given class [element] has a method, getter or setter |
| 5916 * matches the name of the passed [ExecutableElement] in either the class itse
lf, or one of | 5696 * that matches the name of the given executable [element] in either the class |
| 5917 * its' mixins that is concrete. | 5697 * itself, or one of its' mixins that is concrete. |
| 5918 * | 5698 * |
| 5919 * By "match", only the name of the member is tested to match, it does not hav
e to equal or be a | 5699 * By "match", only the name of the member is tested to match, it does not |
| 5920 * subtype of the passed executable element, this is due to the specific use w
here this method is | 5700 * have to equal or be a subtype of the given executable element, this is due |
| 5921 * used in [checkForNonAbstractClassInheritsAbstractMember]. | 5701 * to the specific use where this method is used in |
| 5922 * | 5702 * [_checkForNonAbstractClassInheritsAbstractMember]. |
| 5923 * @param executableElt the executable to search for in the passed class eleme
nt | |
| 5924 * @param classElt the class method to search through the members of | |
| 5925 * @return `true` iff the passed member is found in the passed class element | |
| 5926 */ | 5703 */ |
| 5927 bool _isMemberInClassOrMixin( | 5704 bool _isMemberInClassOrMixin( |
| 5928 ExecutableElement executableElt, ClassElement classElt) { | 5705 ExecutableElement executableElt, ClassElement classElt) { |
| 5929 ExecutableElement foundElt = null; | 5706 ExecutableElement foundElt = null; |
| 5930 String executableName = executableElt.name; | 5707 String executableName = executableElt.name; |
| 5931 if (executableElt is MethodElement) { | 5708 if (executableElt is MethodElement) { |
| 5932 foundElt = classElt.getMethod(executableName); | 5709 foundElt = classElt.getMethod(executableName); |
| 5933 if (foundElt != null && !(foundElt as MethodElement).isAbstract) { | 5710 if (foundElt != null && !(foundElt as MethodElement).isAbstract) { |
| 5934 return true; | 5711 return true; |
| 5935 } | 5712 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 5961 } | 5738 } |
| 5962 if (foundElt != null && | 5739 if (foundElt != null && |
| 5963 !(foundElt as PropertyAccessorElement).isAbstract) { | 5740 !(foundElt as PropertyAccessorElement).isAbstract) { |
| 5964 return true; | 5741 return true; |
| 5965 } | 5742 } |
| 5966 } | 5743 } |
| 5967 return false; | 5744 return false; |
| 5968 } | 5745 } |
| 5969 | 5746 |
| 5970 /** | 5747 /** |
| 5971 * @param node the 'this' expression to analyze | 5748 * Return `true` if the given 'this' [expression] is in a valid context. |
| 5972 * @return `true` if the given 'this' expression is in the valid context | |
| 5973 */ | 5749 */ |
| 5974 bool _isThisInValidContext(ThisExpression node) { | 5750 bool _isThisInValidContext(ThisExpression node) { |
| 5975 for (AstNode n = node; n != null; n = n.parent) { | 5751 for (AstNode n = node; n != null; n = n.parent) { |
| 5976 if (n is CompilationUnit) { | 5752 if (n is CompilationUnit) { |
| 5977 return false; | 5753 return false; |
| 5978 } | 5754 } |
| 5979 if (n is ConstructorDeclaration) { | 5755 if (n is ConstructorDeclaration) { |
| 5980 return n.factoryKeyword == null; | 5756 return n.factoryKeyword == null; |
| 5981 } | 5757 } |
| 5982 if (n is ConstructorInitializer) { | 5758 if (n is ConstructorInitializer) { |
| 5983 return false; | 5759 return false; |
| 5984 } | 5760 } |
| 5985 if (n is MethodDeclaration) { | 5761 if (n is MethodDeclaration) { |
| 5986 return !n.isStatic; | 5762 return !n.isStatic; |
| 5987 } | 5763 } |
| 5988 } | 5764 } |
| 5989 return false; | 5765 return false; |
| 5990 } | 5766 } |
| 5991 | 5767 |
| 5992 /** | 5768 /** |
| 5993 * Return `true` if the given identifier is in a location where it is allowed
to resolve to | 5769 * Return `true` if the given [identifier] is in a location where it is |
| 5994 * a static member of a supertype. | 5770 * allowed to resolve to a static member of a supertype. |
| 5995 * | |
| 5996 * @param node the node being tested | |
| 5997 * @return `true` if the given identifier is in a location where it is allowed
to resolve to | |
| 5998 * a static member of a supertype | |
| 5999 */ | 5771 */ |
| 6000 bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed( | 5772 bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed( |
| 6001 SimpleIdentifier node) { | 5773 SimpleIdentifier node) { |
| 6002 if (node.inDeclarationContext()) { | 5774 if (node.inDeclarationContext()) { |
| 6003 return true; | 5775 return true; |
| 6004 } | 5776 } |
| 6005 AstNode parent = node.parent; | 5777 AstNode parent = node.parent; |
| 6006 if (parent is ConstructorName || | 5778 if (parent is ConstructorName || |
| 6007 parent is MethodInvocation || | 5779 parent is MethodInvocation || |
| 6008 parent is PropertyAccess || | 5780 parent is PropertyAccess || |
| (...skipping 12 matching lines...) Expand all Loading... |
| 6021 return true; | 5793 return true; |
| 6022 } | 5794 } |
| 6023 } | 5795 } |
| 6024 return false; | 5796 return false; |
| 6025 } | 5797 } |
| 6026 | 5798 |
| 6027 bool _isUserDefinedObject(EvaluationResultImpl result) => result == null || | 5799 bool _isUserDefinedObject(EvaluationResultImpl result) => result == null || |
| 6028 (result.value != null && result.value.isUserDefinedObject); | 5800 (result.value != null && result.value.isUserDefinedObject); |
| 6029 | 5801 |
| 6030 /** | 5802 /** |
| 6031 * This checks the class declaration is not a superinterface to itself. | 5803 * Check that the given class [element] is not a superinterface to itself. The |
| 5804 * [path] is a list containing the potentially cyclic implements path. |
| 6032 * | 5805 * |
| 6033 * @param classElt the class element to test | |
| 6034 * @param path a list containing the potentially cyclic implements path | |
| 6035 * @return `true` if and only if an error code is generated on the passed elem
ent | |
| 6036 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], | 5806 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], |
| 6037 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], | 5807 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], |
| 6038 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]
, and | 5808 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]
, |
| 6039 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH]. | 5809 * and [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH]. |
| 6040 */ | 5810 */ |
| 6041 bool _safeCheckForRecursiveInterfaceInheritance( | 5811 bool _safeCheckForRecursiveInterfaceInheritance( |
| 6042 ClassElement classElt, List<ClassElement> path) { | 5812 ClassElement classElt, List<ClassElement> path) { |
| 6043 // Detect error condition. | 5813 // Detect error condition. |
| 6044 int size = path.length; | 5814 int size = path.length; |
| 6045 // If this is not the base case (size > 0), and the enclosing class is the | 5815 // If this is not the base case (size > 0), and the enclosing class is the |
| 6046 // passed class element then an error an error. | 5816 // given class element then an error an error. |
| 6047 if (size > 0 && _enclosingClass == classElt) { | 5817 if (size > 0 && _enclosingClass == classElt) { |
| 6048 String enclosingClassName = _enclosingClass.displayName; | 5818 String enclosingClassName = _enclosingClass.displayName; |
| 6049 if (size > 1) { | 5819 if (size > 1) { |
| 6050 // Construct a string showing the cyclic implements path: | 5820 // Construct a string showing the cyclic implements path: |
| 6051 // "A, B, C, D, A" | 5821 // "A, B, C, D, A" |
| 6052 String separator = ", "; | 5822 String separator = ", "; |
| 6053 StringBuffer buffer = new StringBuffer(); | 5823 StringBuffer buffer = new StringBuffer(); |
| 6054 for (int i = 0; i < size; i++) { | 5824 for (int i = 0; i < size; i++) { |
| 6055 buffer.write(path[i].displayName); | 5825 buffer.write(path[i].displayName); |
| 6056 buffer.write(separator); | 5826 buffer.write(separator); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6094 for (InterfaceType mixinType in mixinTypes) { | 5864 for (InterfaceType mixinType in mixinTypes) { |
| 6095 if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) { | 5865 if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) { |
| 6096 return true; | 5866 return true; |
| 6097 } | 5867 } |
| 6098 } | 5868 } |
| 6099 path.removeAt(path.length - 1); | 5869 path.removeAt(path.length - 1); |
| 6100 return false; | 5870 return false; |
| 6101 } | 5871 } |
| 6102 | 5872 |
| 6103 /** | 5873 /** |
| 6104 * Return the static type of the given expression that is to be used for type
analysis. | 5874 * Return the static type of the given [expression] that is to be used for |
| 6105 * | 5875 * type analysis. |
| 6106 * @param expression the expression whose type is to be returned | |
| 6107 * @return the static type of the given expression | |
| 6108 */ | 5876 */ |
| 6109 static DartType getStaticType(Expression expression) { | 5877 static DartType getStaticType(Expression expression) { |
| 6110 DartType type = expression.staticType; | 5878 DartType type = expression.staticType; |
| 6111 if (type == null) { | 5879 if (type == null) { |
| 6112 // TODO(brianwilkerson) This should never happen. | 5880 // TODO(brianwilkerson) This should never happen. |
| 6113 return DynamicTypeImpl.instance; | 5881 return DynamicTypeImpl.instance; |
| 6114 } | 5882 } |
| 6115 return type; | 5883 return type; |
| 6116 } | 5884 } |
| 6117 | 5885 |
| 6118 /** | 5886 /** |
| 6119 * Return the variable element represented by the given expression, or `null`
if there is no | 5887 * Return the variable element represented by the given [expression], or |
| 6120 * such element. | 5888 * `null` if there is no such element. |
| 6121 * | |
| 6122 * @param expression the expression whose element is to be returned | |
| 6123 * @return the variable element represented by the expression | |
| 6124 */ | 5889 */ |
| 6125 static VariableElement getVariableElement(Expression expression) { | 5890 static VariableElement getVariableElement(Expression expression) { |
| 6126 if (expression is Identifier) { | 5891 if (expression is Identifier) { |
| 6127 Element element = expression.staticElement; | 5892 Element element = expression.staticElement; |
| 6128 if (element is VariableElement) { | 5893 if (element is VariableElement) { |
| 6129 return element; | 5894 return element; |
| 6130 } | 5895 } |
| 6131 } | 5896 } |
| 6132 return null; | 5897 return null; |
| 6133 } | 5898 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6172 toCheck.add(type.element); | 5937 toCheck.add(type.element); |
| 6173 // type arguments | 5938 // type arguments |
| 6174 if (type is InterfaceType) { | 5939 if (type is InterfaceType) { |
| 6175 InterfaceType interfaceType = type; | 5940 InterfaceType interfaceType = type; |
| 6176 for (DartType typeArgument in interfaceType.typeArguments) { | 5941 for (DartType typeArgument in interfaceType.typeArguments) { |
| 6177 _addTypeToCheck(typeArgument); | 5942 _addTypeToCheck(typeArgument); |
| 6178 } | 5943 } |
| 6179 } | 5944 } |
| 6180 } | 5945 } |
| 6181 } | 5946 } |
| OLD | NEW |