| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be | 5 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be |
| 6 // refactored to fit into analyzer. | 6 // refactored to fit into analyzer. |
| 7 library analyzer.src.task.strong.checker; | 7 library analyzer.src.task.strong.checker; |
| 8 | 8 |
| 9 import 'dart:collection'; | 9 import 'dart:collection'; |
| 10 import 'package:analyzer/analyzer.dart'; | 10 import 'package:analyzer/analyzer.dart'; |
| (...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1233 } | 1233 } |
| 1234 } | 1234 } |
| 1235 } | 1235 } |
| 1236 } | 1236 } |
| 1237 | 1237 |
| 1238 void validateIdentifierElement(AstNode n, Element e) { | 1238 void validateIdentifierElement(AstNode n, Element e) { |
| 1239 if (e == null) { | 1239 if (e == null) { |
| 1240 return; | 1240 return; |
| 1241 } | 1241 } |
| 1242 | 1242 |
| 1243 Element enclosing = e.enclosingElement; | 1243 if (e is PropertyAccessorElement) { |
| 1244 if (enclosing is CompilationUnitElement) { | 1244 validateHasType(e); |
| 1245 if (e is PropertyAccessorElement) { | |
| 1246 validateHasType(e); | |
| 1247 } | |
| 1248 } else if (enclosing is ClassElement) { | |
| 1249 if (e is PropertyAccessorElement) { | |
| 1250 if (e.isStatic) { | |
| 1251 validateHasType(e); | |
| 1252 } else { | |
| 1253 _recordMessage( | |
| 1254 n, StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, [name, e.name]); | |
| 1255 } | |
| 1256 } | |
| 1257 } | 1245 } |
| 1258 } | 1246 } |
| 1259 | 1247 |
| 1260 if (n == null || | 1248 if (n == null || |
| 1261 n is NullLiteral || | 1249 n is NullLiteral || |
| 1262 n is BooleanLiteral || | 1250 n is BooleanLiteral || |
| 1263 n is DoubleLiteral || | 1251 n is DoubleLiteral || |
| 1264 n is IntegerLiteral || | 1252 n is IntegerLiteral || |
| 1265 n is StringLiteral || | 1253 n is StringLiteral || |
| 1266 n is SymbolLiteral || | 1254 n is SymbolLiteral || |
| 1267 n is IndexExpression) { | 1255 n is IndexExpression) { |
| 1268 // Nothing to validate. | 1256 // Nothing to validate. |
| 1269 } else if (n is AwaitExpression) { | 1257 } else if (n is AwaitExpression) { |
| 1270 _validateTopLevelInitializer(name, n.expression); | 1258 _validateTopLevelInitializer(name, n.expression); |
| 1271 } else if (n is ThrowExpression) { | 1259 } else if (n is ThrowExpression) { |
| 1272 // Nothing to validate. | 1260 // Nothing to validate. |
| 1273 } else if (n is ParenthesizedExpression) { | 1261 } else if (n is ParenthesizedExpression) { |
| 1274 _validateTopLevelInitializer(name, n.expression); | 1262 _validateTopLevelInitializer(name, n.expression); |
| 1275 } else if (n is ConditionalExpression) { | 1263 } else if (n is ConditionalExpression) { |
| 1276 _validateTopLevelInitializer(name, n.thenExpression); | 1264 _validateTopLevelInitializer(name, n.thenExpression); |
| 1277 _validateTopLevelInitializer(name, n.elseExpression); | 1265 _validateTopLevelInitializer(name, n.elseExpression); |
| 1278 } else if (n is BinaryExpression) { | 1266 } else if (n is BinaryExpression) { |
| 1279 TokenType operator = n.operator.type; | 1267 TokenType operator = n.operator.type; |
| 1280 if (operator == TokenType.AMPERSAND_AMPERSAND || | 1268 if (operator == TokenType.AMPERSAND_AMPERSAND || |
| 1281 operator == TokenType.BAR_BAR || | 1269 operator == TokenType.BAR_BAR || |
| 1282 operator == TokenType.EQ_EQ || | 1270 operator == TokenType.EQ_EQ || |
| 1283 operator == TokenType.BANG_EQ) { | 1271 operator == TokenType.BANG_EQ) { |
| 1284 // These operators give 'bool', no need to validate operands. | 1272 // These operators give 'bool', no need to validate operands. |
| 1285 } else if (operator == TokenType.QUESTION_QUESTION) { | 1273 } else if (operator == TokenType.QUESTION_QUESTION) { |
| 1286 _recordMessage(n, StrongModeCode.TOP_LEVEL_UNSUPPORTED, | 1274 _validateTopLevelInitializer(name, n.leftOperand); |
| 1287 [name, n.runtimeType.toString()]); | 1275 _validateTopLevelInitializer(name, n.rightOperand); |
| 1288 } else { | 1276 } else { |
| 1289 _validateTopLevelInitializer(name, n.leftOperand); | 1277 _validateTopLevelInitializer(name, n.leftOperand); |
| 1290 } | 1278 } |
| 1291 } else if (n is PrefixExpression) { | 1279 } else if (n is PrefixExpression) { |
| 1292 TokenType operator = n.operator.type; | 1280 TokenType operator = n.operator.type; |
| 1293 if (operator == TokenType.BANG) { | 1281 if (operator == TokenType.BANG) { |
| 1294 // This operator gives 'bool', no need to validate operands. | 1282 // This operator gives 'bool', no need to validate operands. |
| 1295 } else { | 1283 } else { |
| 1296 _validateTopLevelInitializer(name, n.operand); | 1284 _validateTopLevelInitializer(name, n.operand); |
| 1297 } | 1285 } |
| 1298 } else if (n is PostfixExpression) { | 1286 } else if (n is PostfixExpression) { |
| 1299 _validateTopLevelInitializer(name, n.operand); | 1287 _validateTopLevelInitializer(name, n.operand); |
| 1300 } else if (n is ListLiteral) { | 1288 } else if (n is ListLiteral) { |
| 1301 if (n.typeArguments == null) { | 1289 if (n.typeArguments == null) { |
| 1302 for (Expression element in n.elements) { | 1290 for (Expression element in n.elements) { |
| 1303 _validateTopLevelInitializer(name, element); | 1291 _validateTopLevelInitializer(name, element); |
| 1304 } | 1292 } |
| 1305 } | 1293 } |
| 1306 } else if (n is MapLiteral) { | 1294 } else if (n is MapLiteral) { |
| 1307 if (n.typeArguments == null) { | 1295 if (n.typeArguments == null) { |
| 1308 for (MapLiteralEntry entry in n.entries) { | 1296 for (MapLiteralEntry entry in n.entries) { |
| 1309 _validateTopLevelInitializer(name, entry.key); | 1297 _validateTopLevelInitializer(name, entry.key); |
| 1310 _validateTopLevelInitializer(name, entry.value); | 1298 _validateTopLevelInitializer(name, entry.value); |
| 1311 } | 1299 } |
| 1312 } | 1300 } |
| 1313 } else if (n is FunctionExpression) { | 1301 } else if (n is FunctionExpression) { |
| 1314 for (FormalParameter p in n.parameters.parameters) { | |
| 1315 if (p is DefaultFormalParameter) { | |
| 1316 p = (p as DefaultFormalParameter).parameter; | |
| 1317 } | |
| 1318 if (p is SimpleFormalParameter) { | |
| 1319 if (p.type == null) { | |
| 1320 _recordMessage( | |
| 1321 p, | |
| 1322 StrongModeCode.TOP_LEVEL_FUNCTION_LITERAL_PARAMETER, | |
| 1323 [name, p.element?.name]); | |
| 1324 } | |
| 1325 } | |
| 1326 } | |
| 1327 | |
| 1328 FunctionBody body = n.body; | 1302 FunctionBody body = n.body; |
| 1329 if (body is ExpressionFunctionBody) { | 1303 if (body is ExpressionFunctionBody) { |
| 1330 _validateTopLevelInitializer(name, body.expression); | 1304 _validateTopLevelInitializer(name, body.expression); |
| 1331 } else { | 1305 } else { |
| 1332 _recordMessage(n, StrongModeCode.TOP_LEVEL_FUNCTION_LITERAL_BLOCK, []); | 1306 _recordMessage(n, StrongModeCode.TOP_LEVEL_FUNCTION_LITERAL_BLOCK, []); |
| 1333 } | 1307 } |
| 1334 } else if (n is InstanceCreationExpression) { | 1308 } else if (n is InstanceCreationExpression) { |
| 1335 ConstructorElement constructor = n.staticElement; | 1309 // Nothing to validate. |
| 1336 ClassElement clazz = constructor?.enclosingElement; | |
| 1337 if (clazz != null && clazz.typeParameters.isNotEmpty) { | |
| 1338 TypeName type = n.constructorName.type; | |
| 1339 if (type.typeArguments == null) { | |
| 1340 _recordMessage(type, StrongModeCode.TOP_LEVEL_TYPE_ARGUMENTS, | |
| 1341 [name, clazz.name]); | |
| 1342 } | |
| 1343 } | |
| 1344 } else if (n is AsExpression) { | 1310 } else if (n is AsExpression) { |
| 1345 // Nothing to validate. | 1311 // Nothing to validate. |
| 1346 } else if (n is IsExpression) { | 1312 } else if (n is IsExpression) { |
| 1347 // Nothing to validate. | 1313 // Nothing to validate. |
| 1348 } else if (n is Identifier) { | 1314 } else if (n is Identifier) { |
| 1349 validateIdentifierElement(n, n.staticElement); | 1315 validateIdentifierElement(n, n.staticElement); |
| 1350 } else if (n is PropertyAccess) { | 1316 } else if (n is PropertyAccess) { |
| 1351 Element element = n.propertyName.staticElement; | 1317 Element element = n.propertyName.staticElement; |
| 1352 validateIdentifierElement(n.propertyName, element); | 1318 validateIdentifierElement(n.propertyName, element); |
| 1353 } else if (n is FunctionExpressionInvocation) { | 1319 } else if (n is FunctionExpressionInvocation) { |
| 1354 _validateTopLevelInitializer(name, n.function); | 1320 _validateTopLevelInitializer(name, n.function); |
| 1355 // TODO(scheglov) type arguments | |
| 1356 } else if (n is MethodInvocation) { | 1321 } else if (n is MethodInvocation) { |
| 1357 _validateTopLevelInitializer(name, n.target); | 1322 _validateTopLevelInitializer(name, n.target); |
| 1358 SimpleIdentifier methodName = n.methodName; | |
| 1359 Element element = methodName.staticElement; | |
| 1360 if (element is ExecutableElement && element.typeParameters.isNotEmpty) { | |
| 1361 if (n.typeArguments == null) { | |
| 1362 _recordMessage(methodName, StrongModeCode.TOP_LEVEL_TYPE_ARGUMENTS, | |
| 1363 [name, methodName.name]); | |
| 1364 } | |
| 1365 } | |
| 1366 } else if (n is CascadeExpression) { | 1323 } else if (n is CascadeExpression) { |
| 1367 _validateTopLevelInitializer(name, n.target); | 1324 _validateTopLevelInitializer(name, n.target); |
| 1368 } else { | |
| 1369 _recordMessage(n, StrongModeCode.TOP_LEVEL_UNSUPPORTED, | |
| 1370 [name, n.runtimeType.toString()]); | |
| 1371 } | 1325 } |
| 1372 } | 1326 } |
| 1373 } | 1327 } |
| 1374 | 1328 |
| 1375 /// Checks for overriding declarations of fields and methods. This is used to | 1329 /// Checks for overriding declarations of fields and methods. This is used to |
| 1376 /// check overrides between classes and superclasses, interfaces, and mixin | 1330 /// check overrides between classes and superclasses, interfaces, and mixin |
| 1377 /// applications. | 1331 /// applications. |
| 1378 class _OverrideChecker { | 1332 class _OverrideChecker { |
| 1379 final StrongTypeSystemImpl rules; | 1333 final StrongTypeSystemImpl rules; |
| 1380 final CodeChecker _checker; | 1334 final CodeChecker _checker; |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2001 } | 1955 } |
| 2002 | 1956 |
| 2003 /// If node is a [ClassDeclaration] returns its members, otherwise if node is | 1957 /// If node is a [ClassDeclaration] returns its members, otherwise if node is |
| 2004 /// a [ClassTypeAlias] this returns an empty list. | 1958 /// a [ClassTypeAlias] this returns an empty list. |
| 2005 WithClause _withClause(Declaration node) { | 1959 WithClause _withClause(Declaration node) { |
| 2006 return node is ClassDeclaration | 1960 return node is ClassDeclaration |
| 2007 ? node.withClause | 1961 ? node.withClause |
| 2008 : (node as ClassTypeAlias).withClause; | 1962 : (node as ClassTypeAlias).withClause; |
| 2009 } | 1963 } |
| 2010 } | 1964 } |
| OLD | NEW |