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 |