OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:collection'; | 6 import 'dart:collection'; |
7 | 7 |
8 import 'package:async_helper/async_helper.dart'; | 8 import 'package:async_helper/async_helper.dart'; |
9 import 'package:expect/expect.dart'; | 9 import 'package:expect/expect.dart'; |
10 import 'package:compiler/src/constants/expressions.dart'; | 10 import 'package:compiler/src/constants/expressions.dart'; |
(...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1292 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR, | 1292 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR, |
1293 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR, | 1293 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR, |
1294 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD, | 1294 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD, |
1295 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD | 1295 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD |
1296 ]); | 1296 ]); |
1297 })); | 1297 })); |
1298 } | 1298 } |
1299 | 1299 |
1300 testCantAssignMethods() { | 1300 testCantAssignMethods() { |
1301 // Can't override local functions | 1301 // Can't override local functions |
1302 checkWarningOn( | 1302 checkWarningOn(''' |
1303 ''' | |
1304 main() { | 1303 main() { |
1305 mname() { mname = 2; }; | 1304 mname() { mname = 2; }; |
1306 mname(); | 1305 mname(); |
1307 } | 1306 } |
1308 ''', | 1307 ''', [MessageKind.ASSIGNING_METHOD]); |
1309 [MessageKind.ASSIGNING_METHOD]); | |
1310 | 1308 |
1311 checkWarningOn( | 1309 checkWarningOn(''' |
1312 ''' | |
1313 main() { | 1310 main() { |
1314 mname() { }; | 1311 mname() { }; |
1315 mname = 3; | 1312 mname = 3; |
1316 } | 1313 } |
1317 ''', | 1314 ''', [MessageKind.ASSIGNING_METHOD]); |
1318 [MessageKind.ASSIGNING_METHOD]); | |
1319 | 1315 |
1320 // Can't override top-level functions | 1316 // Can't override top-level functions |
1321 checkWarningOn( | 1317 checkWarningOn(''' |
1322 ''' | |
1323 m() {} | 1318 m() {} |
1324 main() { m = 4; } | 1319 main() { m = 4; } |
1325 ''', | 1320 ''', [ |
1326 [ | 1321 MessageKind.ASSIGNING_METHOD, |
1327 MessageKind.ASSIGNING_METHOD, | 1322 // TODO(johnniwinther): Avoid duplicate warnings. |
1328 // TODO(johnniwinther): Avoid duplicate warnings. | 1323 MessageKind.NOT_ASSIGNABLE |
1329 MessageKind.NOT_ASSIGNABLE | 1324 ]); |
1330 ]); | |
1331 | 1325 |
1332 // Can't override instance methods | 1326 // Can't override instance methods |
1333 checkWarningOn( | 1327 checkWarningOn(''' |
1334 ''' | |
1335 main() { new B().bar(); } | 1328 main() { new B().bar(); } |
1336 class B { | 1329 class B { |
1337 mname() {} | 1330 mname() {} |
1338 bar() { | 1331 bar() { |
1339 mname = () => null; | 1332 mname = () => null; |
1340 } | 1333 } |
1341 } | 1334 } |
1342 ''', | 1335 ''', [MessageKind.UNDEFINED_SETTER]); |
1343 [MessageKind.UNDEFINED_SETTER]); | 1336 checkWarningOn(''' |
1344 checkWarningOn( | |
1345 ''' | |
1346 main() { new B().bar(); } | 1337 main() { new B().bar(); } |
1347 class B { | 1338 class B { |
1348 mname() {} | 1339 mname() {} |
1349 bar() { | 1340 bar() { |
1350 this.mname = () => null; | 1341 this.mname = () => null; |
1351 } | 1342 } |
1352 } | 1343 } |
1353 ''', | 1344 ''', [MessageKind.UNDEFINED_SETTER]); |
1354 [MessageKind.UNDEFINED_SETTER]); | |
1355 | 1345 |
1356 // Can't override super methods | 1346 // Can't override super methods |
1357 checkWarningOn( | 1347 checkWarningOn(''' |
1358 ''' | |
1359 main() { new B().bar(); } | 1348 main() { new B().bar(); } |
1360 class A { | 1349 class A { |
1361 mname() {} | 1350 mname() {} |
1362 } | 1351 } |
1363 class B extends A { | 1352 class B extends A { |
1364 bar() { | 1353 bar() { |
1365 super.mname = () => 6; | 1354 super.mname = () => 6; |
1366 } | 1355 } |
1367 } | 1356 } |
1368 ''', | 1357 ''', [ |
1369 [ | 1358 MessageKind.ASSIGNING_METHOD_IN_SUPER, |
1370 MessageKind.ASSIGNING_METHOD_IN_SUPER, | 1359 // TODO(johnniwinther): Avoid duplicate warnings. |
1371 // TODO(johnniwinther): Avoid duplicate warnings. | 1360 MessageKind.UNDEFINED_SETTER |
1372 MessageKind.UNDEFINED_SETTER | 1361 ]); |
1373 ]); | |
1374 | 1362 |
1375 // But index operators should be OK | 1363 // But index operators should be OK |
1376 checkWarningOn( | 1364 checkWarningOn(''' |
1377 ''' | |
1378 main() { new B().bar(); } | 1365 main() { new B().bar(); } |
1379 class B { | 1366 class B { |
1380 operator[]=(x, y) {} | 1367 operator[]=(x, y) {} |
1381 bar() { | 1368 bar() { |
1382 this[1] = 3; // This is OK | 1369 this[1] = 3; // This is OK |
1383 } | 1370 } |
1384 } | 1371 } |
1385 ''', | 1372 ''', []); |
1386 []); | 1373 checkWarningOn(''' |
1387 checkWarningOn( | |
1388 ''' | |
1389 main() { new B().bar(); } | 1374 main() { new B().bar(); } |
1390 class A { | 1375 class A { |
1391 operator[]=(x, y) {} | 1376 operator[]=(x, y) {} |
1392 } | 1377 } |
1393 class B extends A { | 1378 class B extends A { |
1394 bar() { | 1379 bar() { |
1395 super[1] = 3; // This is OK | 1380 super[1] = 3; // This is OK |
1396 } | 1381 } |
1397 } | 1382 } |
1398 ''', | 1383 ''', []); |
1399 []); | |
1400 } | 1384 } |
1401 | 1385 |
1402 testCantAssignFinalAndConsts() { | 1386 testCantAssignFinalAndConsts() { |
1403 // Can't write final or const locals. | 1387 // Can't write final or const locals. |
1404 checkWarningOn( | 1388 checkWarningOn(''' |
1405 ''' | |
1406 main() { | 1389 main() { |
1407 final x = 1; | 1390 final x = 1; |
1408 x = 2; | 1391 x = 2; |
1409 } | 1392 } |
1410 ''', | 1393 ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); |
1411 [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); | 1394 checkWarningOn(''' |
1412 checkWarningOn( | |
1413 ''' | |
1414 main() { | 1395 main() { |
1415 const x = 1; | 1396 const x = 1; |
1416 x = 2; | 1397 x = 2; |
1417 } | 1398 } |
1418 ''', | 1399 ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); |
1419 [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); | 1400 checkWarningOn(''' |
1420 checkWarningOn( | |
1421 ''' | |
1422 final x = 1; | 1401 final x = 1; |
1423 main() { x = 3; } | 1402 main() { x = 3; } |
1424 ''', | 1403 ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); |
1425 [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); | |
1426 | 1404 |
1427 checkWarningOn( | 1405 checkWarningOn(''' |
1428 ''' | |
1429 const x = 1; | 1406 const x = 1; |
1430 main() { x = 3; } | 1407 main() { x = 3; } |
1431 ''', | 1408 ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); |
1432 [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); | |
1433 | 1409 |
1434 // Detect assignments to final fields: | 1410 // Detect assignments to final fields: |
1435 checkWarningOn( | 1411 checkWarningOn(''' |
1436 ''' | |
1437 main() => new B().m(); | 1412 main() => new B().m(); |
1438 class B { | 1413 class B { |
1439 final x = 1; | 1414 final x = 1; |
1440 m() { x = 2; } | 1415 m() { x = 2; } |
1441 } | 1416 } |
1442 ''', | 1417 ''', [MessageKind.UNDEFINED_SETTER]); |
1443 [MessageKind.UNDEFINED_SETTER]); | |
1444 | 1418 |
1445 // ... even if 'this' is explicit: | 1419 // ... even if 'this' is explicit: |
1446 checkWarningOn( | 1420 checkWarningOn(''' |
1447 ''' | |
1448 main() => new B().m(); | 1421 main() => new B().m(); |
1449 class B { | 1422 class B { |
1450 final x = 1; | 1423 final x = 1; |
1451 m() { this.x = 2; } | 1424 m() { this.x = 2; } |
1452 } | 1425 } |
1453 ''', | 1426 ''', [MessageKind.UNDEFINED_SETTER]); |
1454 [MessageKind.UNDEFINED_SETTER]); | |
1455 | 1427 |
1456 // ... and in super class: | 1428 // ... and in super class: |
1457 checkWarningOn( | 1429 checkWarningOn(''' |
1458 ''' | |
1459 main() => new B().m(); | 1430 main() => new B().m(); |
1460 class A { | 1431 class A { |
1461 final x = 1; | 1432 final x = 1; |
1462 } | 1433 } |
1463 class B extends A { | 1434 class B extends A { |
1464 m() { super.x = 2; } | 1435 m() { super.x = 2; } |
1465 } | 1436 } |
1466 ''', | 1437 ''', [ |
1467 [ | 1438 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, |
1468 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, | 1439 // TODO(johnniwinther): Avoid duplicate warnings. |
1469 // TODO(johnniwinther): Avoid duplicate warnings. | 1440 MessageKind.UNDEFINED_SETTER |
1470 MessageKind.UNDEFINED_SETTER | 1441 ]); |
1471 ]); | |
1472 | 1442 |
1473 // But non-final fields are OK: | 1443 // But non-final fields are OK: |
1474 checkWarningOn( | 1444 checkWarningOn(''' |
1475 ''' | |
1476 main() => new B().m(); | 1445 main() => new B().m(); |
1477 class A { | 1446 class A { |
1478 int x = 1; | 1447 int x = 1; |
1479 } | 1448 } |
1480 class B extends A { | 1449 class B extends A { |
1481 m() { super.x = 2; } | 1450 m() { super.x = 2; } |
1482 } | 1451 } |
1483 ''', | 1452 ''', []); |
1484 []); | |
1485 | 1453 |
1486 // Check getter without setter. | 1454 // Check getter without setter. |
1487 checkWarningOn( | 1455 checkWarningOn(''' |
1488 ''' | |
1489 main() => new B().m(); | 1456 main() => new B().m(); |
1490 class A { | 1457 class A { |
1491 get x => 1; | 1458 get x => 1; |
1492 } | 1459 } |
1493 class B extends A { | 1460 class B extends A { |
1494 m() { super.x = 2; } | 1461 m() { super.x = 2; } |
1495 } | 1462 } |
1496 ''', | 1463 ''', [ |
1497 [ | 1464 MessageKind.UNDEFINED_SUPER_SETTER, |
1498 MessageKind.UNDEFINED_SUPER_SETTER, | 1465 // TODO(johnniwinther): Avoid duplicate warnings. |
1499 // TODO(johnniwinther): Avoid duplicate warnings. | 1466 MessageKind.UNDEFINED_SETTER |
1500 MessageKind.UNDEFINED_SETTER | 1467 ]); |
1501 ]); | |
1502 } | 1468 } |
1503 | 1469 |
1504 /// Helper to test that [script] produces all the given [warnings]. | 1470 /// Helper to test that [script] produces all the given [warnings]. |
1505 checkWarningOn(String script, List<MessageKind> warnings) { | 1471 checkWarningOn(String script, List<MessageKind> warnings) { |
1506 Expect.isTrue(warnings.length >= 0 && warnings.length <= 2); | 1472 Expect.isTrue(warnings.length >= 0 && warnings.length <= 2); |
1507 asyncTest(() => compileScript(script).then((compiler) { | 1473 asyncTest(() => compileScript(script).then((compiler) { |
1508 DiagnosticCollector collector = compiler.diagnosticCollector; | 1474 DiagnosticCollector collector = compiler.diagnosticCollector; |
1509 Expect.equals(0, collector.errors.length, | 1475 Expect.equals(0, collector.errors.length, |
1510 'Unexpected errors in\n$script\n${collector.errors}'); | 1476 'Unexpected errors in\n$script\n${collector.errors}'); |
1511 Expect.equals( | 1477 Expect.equals( |
(...skipping 22 matching lines...) Expand all Loading... |
1534 Expect.equals( | 1500 Expect.equals( |
1535 "$prefix.\n" | 1501 "$prefix.\n" |
1536 "Did you mean to add the 'async' marker to $where?", | 1502 "Did you mean to add the 'async' marker to $where?", |
1537 '${collector.warnings.first.message}'); | 1503 '${collector.warnings.first.message}'); |
1538 })); | 1504 })); |
1539 } | 1505 } |
1540 | 1506 |
1541 check('main() { await -3; }', functionName: 'main'); | 1507 check('main() { await -3; }', functionName: 'main'); |
1542 check('main() { () => await -3; }'); | 1508 check('main() { () => await -3; }'); |
1543 check('foo() => await -3; main() => foo();', functionName: 'foo'); | 1509 check('foo() => await -3; main() => foo();', functionName: 'foo'); |
1544 check( | 1510 check(''' |
1545 ''' | |
1546 class A { | 1511 class A { |
1547 m() => await - 3; | 1512 m() => await - 3; |
1548 } | 1513 } |
1549 main() => new A().m(); | 1514 main() => new A().m(); |
1550 ''', | 1515 ''', className: 'A', functionName: 'm'); |
1551 className: 'A', | 1516 check(''' |
1552 functionName: 'm'); | |
1553 check( | |
1554 ''' | |
1555 class A { | 1517 class A { |
1556 static m() => await - 3; | 1518 static m() => await - 3; |
1557 } | 1519 } |
1558 main() => A.m(); | 1520 main() => A.m(); |
1559 ''', | 1521 ''', functionName: 'm'); |
1560 functionName: 'm'); | 1522 check(''' |
1561 check( | |
1562 ''' | |
1563 class A { | 1523 class A { |
1564 m() => () => await - 3; | 1524 m() => () => await - 3; |
1565 } | 1525 } |
1566 main() => new A().m(); | 1526 main() => new A().m(); |
1567 ''', | 1527 ''', className: 'A'); |
1568 className: 'A'); | |
1569 } | 1528 } |
OLD | NEW |