| 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 part of dart2js; | 5 part of dart2js; |
| 6 | 6 |
| 7 class TypeCheckerTask extends CompilerTask { | 7 class TypeCheckerTask extends CompilerTask { |
| 8 TypeCheckerTask(Compiler compiler) : super(compiler); | 8 TypeCheckerTask(Compiler compiler) : super(compiler); |
| 9 String get name => "Type checker"; | 9 String get name => "Type checker"; |
| 10 | 10 |
| (...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1232 | 1232 |
| 1233 reshowTypePromotions(node, receiver, argument); | 1233 reshowTypePromotions(node, receiver, argument); |
| 1234 | 1234 |
| 1235 checkAssignable(argument, argumentType, boolType); | 1235 checkAssignable(argument, argumentType, boolType); |
| 1236 return boolType; | 1236 return boolType; |
| 1237 } else if (identical(name, '!')) { | 1237 } else if (identical(name, '!')) { |
| 1238 checkAssignable(receiver, receiverType, boolType); | 1238 checkAssignable(receiver, receiverType, boolType); |
| 1239 return boolType; | 1239 return boolType; |
| 1240 } else if (identical(name, '?')) { | 1240 } else if (identical(name, '?')) { |
| 1241 return boolType; | 1241 return boolType; |
| 1242 } else if (identical(name, '??')) { |
| 1243 final Node argument = node.arguments.head; |
| 1244 final DartType argumentType = analyze(argument); |
| 1245 return types.computeLeastUpperBound(receiverType, argumentType); |
| 1242 } | 1246 } |
| 1243 String operatorName = selector.source; | 1247 String operatorName = selector.source; |
| 1244 if (identical(name, '-') && node.arguments.isEmpty) { | 1248 if (identical(name, '-') && node.arguments.isEmpty) { |
| 1245 operatorName = 'unary-'; | 1249 operatorName = 'unary-'; |
| 1246 } | 1250 } |
| 1247 assert(invariant(node, | 1251 assert(invariant(node, |
| 1248 identical(name, '+') || identical(name, '=') || | 1252 identical(name, '+') || identical(name, '=') || |
| 1249 identical(name, '-') || identical(name, '*') || | 1253 identical(name, '-') || identical(name, '*') || |
| 1250 identical(name, '/') || identical(name, '%') || | 1254 identical(name, '/') || identical(name, '%') || |
| 1251 identical(name, '~/') || identical(name, '|') || | 1255 identical(name, '~/') || identical(name, '|') || |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1400 return node.isPostfix ? element : result; | 1404 return node.isPostfix ? element : result; |
| 1401 } | 1405 } |
| 1402 } | 1406 } |
| 1403 return const DynamicType(); | 1407 return const DynamicType(); |
| 1404 } | 1408 } |
| 1405 | 1409 |
| 1406 visitSendSet(SendSet node) { | 1410 visitSendSet(SendSet node) { |
| 1407 Element element = elements[node]; | 1411 Element element = elements[node]; |
| 1408 Identifier selector = node.selector; | 1412 Identifier selector = node.selector; |
| 1409 final name = node.assignmentOperator.source; | 1413 final name = node.assignmentOperator.source; |
| 1410 if (identical(name, '=')) { | 1414 if (identical(name, '=') || identical(name, '??=')) { |
| 1411 // e1 = value | 1415 // e1 = value |
| 1412 if (node.isIndex) { | 1416 if (node.isIndex) { |
| 1413 // base[key] = value | 1417 // base[key] = value |
| 1414 final DartType base = analyze(node.receiver); | 1418 final DartType base = analyze(node.receiver); |
| 1415 final Node keyNode = node.arguments.head; | 1419 final Node keyNode = node.arguments.head; |
| 1416 final DartType key = analyze(keyNode); | 1420 final DartType key = analyze(keyNode); |
| 1417 final Node valueNode = node.arguments.tail.head; | 1421 final Node valueNode = node.arguments.tail.head; |
| 1418 final DartType value = analyze(valueNode); | 1422 final DartType value = analyze(valueNode); |
| 1419 DartType indexSet = lookupMemberType( | 1423 DartType indexSet = lookupMemberType( |
| 1420 node, base, '[]=', MemberKind.OPERATOR); | 1424 node, base, '[]=', MemberKind.OPERATOR); |
| 1425 DartType indexSetValue = const DynamicType(); |
| 1421 if (indexSet is FunctionType) { | 1426 if (indexSet is FunctionType) { |
| 1422 FunctionType indexSetType = indexSet; | 1427 FunctionType indexSetType = indexSet; |
| 1423 DartType indexSetKey = firstType(indexSetType.parameterTypes); | 1428 DartType indexSetKey = firstType(indexSetType.parameterTypes); |
| 1424 checkAssignable(keyNode, key, indexSetKey); | 1429 checkAssignable(keyNode, key, indexSetKey); |
| 1425 DartType indexSetValue = secondType(indexSetType.parameterTypes); | 1430 indexSetValue = secondType(indexSetType.parameterTypes); |
| 1426 checkAssignable(node.assignmentOperator, value, indexSetValue); | 1431 checkAssignable(node.assignmentOperator, value, indexSetValue); |
| 1427 } | 1432 } |
| 1428 return value; | 1433 return identical(name, '=') ? value |
| 1434 : types.computeLeastUpperBound(value, indexSetValue); |
| 1429 } else { | 1435 } else { |
| 1430 // target = value | 1436 // target = value |
| 1431 DartType target; | 1437 DartType target; |
| 1432 if (analyzingInitializer) { | 1438 if (analyzingInitializer) { |
| 1433 // Field declaration `Foo target = value;` or initializer | 1439 // Field declaration `Foo target = value;` or initializer |
| 1434 // `this.target = value`. Lookup the getter `target` in the class | 1440 // `this.target = value`. Lookup the getter `target` in the class |
| 1435 // members. | 1441 // members. |
| 1436 target = computeAccessType(node, selector.source, element, | 1442 target = computeAccessType(node, selector.source, element, |
| 1437 MemberKind.GETTER, lookupClassMember: true); | 1443 MemberKind.GETTER, lookupClassMember: true); |
| 1438 } else { | 1444 } else { |
| 1439 // Normal assignment `target = value`. | 1445 // Normal assignment `target = value`. |
| 1440 target = computeAccessType( | 1446 target = computeAccessType( |
| 1441 node, selector.source, element, MemberKind.SETTER); | 1447 node, selector.source, element, MemberKind.SETTER); |
| 1442 } | 1448 } |
| 1443 final Node valueNode = node.arguments.head; | 1449 final Node valueNode = node.arguments.head; |
| 1444 final DartType value = analyze(valueNode); | 1450 final DartType value = analyze(valueNode); |
| 1445 checkAssignable(node.assignmentOperator, value, target); | 1451 checkAssignable(node.assignmentOperator, value, target); |
| 1446 return value; | 1452 return identical(name, '=') ? value |
| 1453 : types.computeLeastUpperBound(value, target); |
| 1447 } | 1454 } |
| 1448 } else if (identical(name, '++') || identical(name, '--')) { | 1455 } else if (identical(name, '++') || identical(name, '--')) { |
| 1449 // e++ or e-- | 1456 // e++ or e-- |
| 1450 String operatorName = identical(name, '++') ? '+' : '-'; | 1457 String operatorName = identical(name, '++') ? '+' : '-'; |
| 1451 if (node.isIndex) { | 1458 if (node.isIndex) { |
| 1452 // base[key]++, base[key]--, ++base[key], or --base[key] | 1459 // base[key]++, base[key]--, ++base[key], or --base[key] |
| 1453 return checkIndexAssignmentOperator( | 1460 return checkIndexAssignmentOperator( |
| 1454 node, operatorName, node.assignmentOperator, intType); | 1461 node, operatorName, node.assignmentOperator, intType); |
| 1455 } else { | 1462 } else { |
| 1456 // target++, target--, ++target, or --target | 1463 // target++, target--, ++target, or --target |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1858 | 1865 |
| 1859 visitTypedef(Typedef node) { | 1866 visitTypedef(Typedef node) { |
| 1860 // Do not typecheck [Typedef] nodes. | 1867 // Do not typecheck [Typedef] nodes. |
| 1861 } | 1868 } |
| 1862 | 1869 |
| 1863 visitNode(Node node) { | 1870 visitNode(Node node) { |
| 1864 compiler.internalError(node, | 1871 compiler.internalError(node, |
| 1865 'Unexpected node ${node.getObjectDescription()} in the type checker.'); | 1872 'Unexpected node ${node.getObjectDescription()} in the type checker.'); |
| 1866 } | 1873 } |
| 1867 } | 1874 } |
| OLD | NEW |