Wiki

Ticket #74: debug_help.patch

File debug_help.patch, 9.3 KB (added by eric.sellon, 8 years ago)
  • Source/Members.cobra

     
    14631463 
    14641464    def _bindImp is override 
    14651465        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 
    14661470 
     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 
    14671488 
     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 
    14681573class TestMethod 
    14691574    is partial 
    14701575    inherits Method 
  • Source/Expr.cobra

     
    583583                            # http://www.google.com/search?hl=en&q=C%23+overloaded+method+resolution 
    584584                            # TODO: handle type inference for generic members. See the C# spec for details. 
    585585                         
    586                             winner = _computeBestOverload(definition, args) 
     586                            winner = definition.computeBestOverload(.args, .genericArgTypes, true) 
    587587                            sharp'definition = winner' 
    588588                            type = winner.resultType 
    589589                        else 
     
    688688                .compiler.recordError(ne) 
    689689            num += 1 
    690690 
    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  
    784693        for param in definition.params 
    785             if param.type inherits VariType  
     694            if param.type inherits VariType 
    786695                hasVari = true 
    787696                break 
    788697        if hasVari 
     
    17571666                _type = .compiler.dynamicType 
    17581667            else if exprType inherits Box 
    17591668                _type = expr.receiverType  # for example, an IdentifierExpr of 'SomeClass' has a .receiverType of that class 
     1669                _handleClassInitializer 
    17601670            else if exprType.isDynamic 
    17611671                _type = .compiler.nilableDynamicType 
    17621672            else if expr.definition inherits NameSpace 
     
    18401750            sep = ', ' 
    18411751        sb.append(')') 
    18421752        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? 
    18431784 
    18441785 
    18451786class RefExpr