Ticket #74: debug_help.patch
File debug_help.patch, 9.3 KB (added by eric.sellon, 15 years ago) |
---|
-
Source/Members.cobra
1463 1463 1464 1464 def _bindImp is override 1465 1465 base._bindImp 1466 1467 def computeBestOverload(args as List<of Expr>, genericArgTypes as List<of IType>?, strictBindChecking as bool) as BoxMember 1468 # References: 1469 # http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx 1466 1470 1471 # I cooked up the algorithm below as a quick way to fix some bugs caused by the previous 1472 # implementation of um, doing nothing. 1473 # But this likely needs to be rewritten. 1474 candidates = [] 1475 # handle generic arguments to the method 1476 if genericArgTypes and genericArgTypes.count 1477 members = List<of BoxMember>() 1478 for member as BoxMember? in .members 1479 if member inherits Method 1480 if member.containsGenericParameters 1481 if member.genericParams.count == genericArgTypes.count 1482 member = member.constructedMethodWith(genericArgTypes to !) 1483 else 1484 member = nil 1485 if member, members.add(member) 1486 else 1487 members = .members 1467 1488 1489 for member in members 1490 score = -1000 1491 #print member.params.count 1492 #print member.params 1493 #print member 1494 if member.params.count == args.count 1495 score = 0 1496 if member inherits Method and (member to Method).genericParams.count > 0, score += 1 1497 for i, param in member.params.numbered 1498 arg = args[i] 1499 if strictBindChecking and not arg.didBindImp 1500 trace arg 1501 trace arg.hasError 1502 if strictBindChecking and (arg.type == param.type or arg.type == param.type.nonNil) 1503 score += 20 1504 else if strictBindChecking and arg.canBeAssignedTo(param.type) 1505 score += 10 1506 else if strictBindChecking and arg.type.nonNil.isAssignableTo(param.type) 1507 # Cobra's code and data flow analysis sometimes leaves us with a nilable type that's not actually nil anymore 1508 # due to an assignment, possibly wrapped in an if statement. Eventually this will be corrected, but for now 1509 # compensate here. 1510 score += 1 1511 else if not strictBindChecking 1512 #print '' 1513 #print param.token 1514 #print arg 1515 if arg.type is not nil 1516 if arg.type == param.type 1517 score += 20 1518 else if arg.type.isDynamic 1519 score += 10 1520 else 1521 score -= 100 1522 else 1523 score -= 100 1524 # print 'candidate:', score, member.name, member.serialNum, Utils.join(', ', (for param in member.params get param.type.name)) 1525 candidates.add([score, member]) 1526 1527 maxScore = -10_000 1528 winner = nil to BoxMember? 1529 for pair in candidates 1530 if false, print pair[0], (pair[1] to BoxMember).idString 1531 if pair[0] to int > maxScore 1532 maxScore = pair[0] to int 1533 winner = pair[1] to BoxMember 1534 1535 if false 1536 # detect overload invocation ambiguity 1537 # TODO: not ready for this yet 1538 count = 0 1539 for pair in candidates 1540 if pair[0] to int == maxScore 1541 count += 1 1542 if count > 1 1543 # TODO: do this for indexing too 1544 msg = 'The call is ambiguous between these methods: ' 1545 sep = '' 1546 for pair in candidates 1547 if pair[0] to int == maxScore 1548 msg += sep + (pair[1] to AbstractMethod).cobraSourceSignature(false) 1549 sep = ', ' 1550 .throwError(msg) 1551 1552 if false 1553 pass 1554 # print 1555 # trace .token.fileName 1556 # trace maxScore, _name 1557 # trace .token.toTechString 1558 # trace winner 1559 # print 'args:' 1560 # for arg in args 1561 # print ' [arg]' 1562 # print 'params:' 1563 # for param in winner.params 1564 # print ' [param]' 1565 # print 'overloads:' 1566 # for member in .members 1567 # print ' [member]' 1568 # print 'winner:', score, winner 1569 assert winner 1570 return winner to ! 1571 1572 1468 1573 class TestMethod 1469 1574 is partial 1470 1575 inherits Method -
Source/Expr.cobra
583 583 # http://www.google.com/search?hl=en&q=C%23+overloaded+method+resolution 584 584 # TODO: handle type inference for generic members. See the C# spec for details. 585 585 586 winner = _computeBestOverload(definition, args)586 winner = definition.computeBestOverload(.args, .genericArgTypes, true) 587 587 sharp'definition = winner' 588 588 type = winner.resultType 589 589 else … … 688 688 .compiler.recordError(ne) 689 689 num += 1 690 690 691 def _computeBestOverload(definition as MemberOverload, args as List<of Expr>) as BoxMember 692 # References: 693 # http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx 694 695 # I cooked up the algorithm below as a quick way to fix some bugs caused by the previous 696 # implementation of um, doing nothing. 697 # But this likely needs to be rewritten. 698 candidates = [] 699 # handle generic arguments to the method 700 genericArgTypes = .genericArgTypes 701 if genericArgTypes and genericArgTypes.count 702 members = List<of BoxMember>() 703 for member as BoxMember? in definition.members 704 if member inherits Method 705 if member.containsGenericParameters 706 if member.genericParams.count == genericArgTypes.count 707 member = member.constructedMethodWith(genericArgTypes to !) 708 else 709 member = nil 710 if member, members.add(member) 711 else 712 members = definition.members 713 714 for member in members 715 score = -1000 716 if member.params.count == args.count 717 score = 0 718 if member inherits Method and (member to Method).genericParams.count > 0, score += 1 719 for i, param in member.params.numbered 720 arg = args[i] 721 if not arg.didBindImp 722 trace arg 723 trace arg.hasError 724 if arg.type == param.type or arg.type == param.type.nonNil 725 score += 20 726 else if arg.canBeAssignedTo(param.type) 727 score += 10 728 else if arg.type.nonNil.isAssignableTo(param.type) 729 # Cobra's code and data flow analysis sometimes leaves us with a nilable type that's not actually nil anymore 730 # due to an assignment, possibly wrapped in an if statement. Eventually this will be corrected, but for now 731 # compensate here. 732 score += 1 733 else 734 score -= 100 735 # print 'candidate:', score, member.name, member.serialNum, Utils.join(', ', (for param in member.params get param.type.name)) 736 candidates.add([score, member]) 737 738 maxScore = -10_000 739 winner = nil to BoxMember? 740 for pair in candidates 741 if false, print pair[0], (pair[1] to BoxMember).idString 742 if pair[0] to int > maxScore 743 maxScore = pair[0] to int 744 winner = pair[1] to BoxMember 745 746 if false 747 # detect overload invocation ambiguity 748 # TODO: not ready for this yet 749 count = 0 750 for pair in candidates 751 if pair[0] to int == maxScore 752 count += 1 753 if count > 1 754 # TODO: do this for indexing too 755 msg = 'The call is ambiguous between these methods: ' 756 sep = '' 757 for pair in candidates 758 if pair[0] to int == maxScore 759 msg += sep + (pair[1] to AbstractMethod).cobraSourceSignature(false) 760 sep = ', ' 761 .throwError(msg) 762 763 if false 764 print 765 trace .token.fileName 766 trace maxScore, _name 767 trace .token.toTechString 768 trace winner 769 print 'args:' 770 for arg in args 771 print ' [arg]' 772 print 'params:' 773 for param in winner.params 774 print ' [param]' 775 print 'overloads:' 776 for member in definition.members 777 print ' [member]' 778 # print 'winner:', score, winner 779 assert winner 780 return winner to ! 781 782 def _didVariArgs(definition as BoxMember) as bool 783 hasVari = false 691 def _didVariArgs(definition as BoxMember) as bool 692 hasVari = false 784 693 for param in definition.params 785 if param.type inherits VariType 694 if param.type inherits VariType 786 695 hasVari = true 787 696 break 788 697 if hasVari … … 1757 1666 _type = .compiler.dynamicType 1758 1667 else if exprType inherits Box 1759 1668 _type = expr.receiverType # for example, an IdentifierExpr of 'SomeClass' has a .receiverType of that class 1669 _handleClassInitializer 1760 1670 else if exprType.isDynamic 1761 1671 _type = .compiler.nilableDynamicType 1762 1672 else if expr.definition inherits NameSpace … … 1840 1750 sep = ', ' 1841 1751 sb.append(')') 1842 1752 return sb.toString 1753 1754 def _handleClassInitializer 1755 initCall as Initializer? 1756 if .args.count > 0 1757 if .name == 'FallThroughException' 1758 mySpecialDebug = true 1759 else 1760 mySpecialDebug = false 1761 theClass = .compiler.symbolForName(.name, true, false, true) to ClassOrStruct? 1762 if mySpecialDebug, print theClass 1763 if theClass is not nil 1764 possibleCalls = theClass.symbolForName("cue.init", true, false) 1765 if mySpecialDebug, print possibleCalls 1766 if possibleCalls is nil 1767 pass # TODO: determine if this is an error or if support for base class init functions need to be added 1768 else if possibleCalls inherits MemberOverload 1769 initCall = possibleCalls.computeBestOverload(.args, nil, false) to Initializer? 1770 else if possibleCalls inherits Initializer 1771 initCall = possibleCalls 1772 #else 1773 # TODO: determine if this is an error 1774 #print initCall 1775 if initCall is not nil and .args.count == initCall.params.count 1776 i = 0 1777 for arg in .args 1778 if arg.type is not nil and arg.type.isDynamic 1779 # set context type so that backend can type cast it correctly 1780 arg.contextType = initCall.params[i].type 1781 i += 1 1782 #else 1783 # TODO: warning or error? 1843 1784 1844 1785 1845 1786 class RefExpr