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