Wiki

Ticket #58: expr-refactor.patch

File expr-refactor.patch, 26.6 KB (added by hopscc, 16 years ago)
  • Source/Expr.cobra

     
    397397 
    398398    def _bindImp is override 
    399399        base._bindImp 
    400  
     400        assert _superNode inherits DotExpr  # otherwise, for something like List<of int>(), the parser creates a PostCallExpr 
    401401        if _genericArgProxies 
    402             assert _superNode inherits DotExpr  # otherwise, for something like List<of int>(), the parser creates a PostCallExpr 
    403             _genericArgTypes = List<of IType>() 
    404             num = 1 
    405             for typeProxy in _genericArgProxies 
    406                 try 
    407                     _genericArgTypes.add(typeProxy.realType) 
    408                 catch ne as NodeException 
    409                     ne.prefixMessage('For "[_name]" type arg [num]: ') 
    410                     .compiler.recordError(ne) 
    411                 num += 1 
    412             # TODO: Check types are compatible with call 
    413  
    414         assert _superNode inherits DotExpr 
     402            _setGenericArgTypes 
    415403        dotNode = _superNode to DotExpr 
    416404        assert this is dotNode.right 
    417405 
    418406        if dotNode.left.didBindImp 
    419407            enumDefi = dotNode.left.memberForName(_name) 
    420408            if enumDefi inherits EnumDecl 
    421                 # Foo.EnumType(MemberA, MemberB) 
    422                 # Change to an EnumCallExpr 
    423                 # Roll up Foo.Bar.Baz() into one EnumCallExpr 
    424                 transformTarget = dotNode 
    425                 while transformTarget.superNode inherits DotExpr 
    426                     transformTarget = transformTarget.superNode to DotExpr 
    427                 enumCall = EnumCallExpr(.token, _name, _args, enumDefi).bindImp 
    428                 _type = enumCall.type to IType 
    429                 transformTarget._transformTo(enumCall) 
     409                _transformEnumDecl(dotNode, enumDefi) 
    430410                return 
    431411 
    432         num = 1 
    433         for arg in _args 
    434             try 
    435                 if arg inherits AssignExpr 
    436                     arg.right.bindImp  # 'x=y' has special treatment in arguments 
    437                 else 
    438                     arg.bindImp 
    439             catch ne as NodeException 
    440                 ne.prefixMessage('For "[_name]" arg [num]: ') 
    441                 .compiler.recordError(ne) 
    442             num += 1 
    443  
     412        _bindImpArgs 
    444413        definition as INamedNode? 
    445414        type as IType? 
    446415 
    447         if _definition is nil  or  _type is nil 
    448             checkName = _name 
    449             while checkName.startsWith('_') 
    450                 checkName = checkName.substring(1) 
     416        if _definition is nil or _type is nil 
    451417            # handle foo.bar() where this is the `bar()` part 
    452418            if not dotNode.left.didBindImp 
    453419                assert dotNode.left.hasError, dotNode.left 
    454420                # we get here for Cobra code like "obj.foo.bar(x)" where "foo" is not found 
    455421                _type = .compiler.passThroughType 
    456422                return  # TODO: I don't think I want a return here 
    457             possibleDefinition = dotNode.left.memberForName(_name) 
    458             if possibleDefinition is nil 
    459                 lrt = dotNode.left.receiverType 
    460                 if lrt.isDynamic 
    461                     type = .compiler.nilableDynamicType 
    462                 else if lrt is .compiler.passThroughType 
    463                     if _name == 'toString' 
    464                         type = .compiler.stringType 
    465                     else 
    466                         type = .compiler.passThroughType 
    467                 else 
    468                     left = dotNode.left 
    469                     suggs = left.suggestionsForBadMemberName(_name) 
    470                     isBoxAccess = left inherits IdentifierExpr and (left to IdentifierExpr).definition inherits Box  # like "Console.writeLine" where the receiver is a literal class or struct reference 
    471                     whoseTypeIs = if(isBoxAccess, '', ' whose type is "[left.receiverType.name]"') 
    472                     .throwError('Cannot find a definition for "[_name]" in "[left.toCobraSource]"[whoseTypeIs].[_suggestionsMessage(suggs)]') 
    473             else 
    474                 if not possibleDefinition.isCallable 
    475                     .throwError('Cannot call "[_name]" because it is a "[possibleDefinition.englishName]".') 
    476                 definition = possibleDefinition 
    477                 type = possibleDefinition.resultType 
     423 
     424            definition = _inferDefinitionAndType(dotNode, definition, out type) 
    478425            assert type 
    479             # assert definition 
    480             if definition inherits IType 
    481                 # Foo.Bar() where Bar is a box/type 
    482                 # Change to a PostCallExpr on the type 'Foo.Bar' 
    483                  
    484                 # Roll up Foo.Bar.Baz() into one PostCallExpr 
    485                 transformTarget = dotNode 
    486                 while transformTarget.superNode inherits DotExpr 
    487                     transformTarget = transformTarget.superNode to DotExpr 
    488                  
    489                 postCall = PostCallExpr(.token, TypeExpr(.token, definition), .args).bindImp 
    490                 _type = postCall.type to IType 
    491                 transformTarget._transformTo(postCall) 
     426            if definition inherits IType    # Box, IVar or GenericParam 
     427                _transformIType(dotNode, definition) 
    492428                return 
     429 
    493430            if definition 
    494431                # definition should never be a Box, IVar or GenericParam as those cases would be handled by the transformation to PostCallExpr above 
    495432                # there is a FallThroughException down below that would report this if it happened 
     
    500437                            # Note that overloads can have different return types (even if more than just the return type is needed to distinguish them). Example: Math. 
    501438                            # Plenty of info here: 
    502439                            # http://www.google.com/search?hl=en&q=C%23+overloaded+method+resolution 
    503  
    504440                            # TODO: handle type inference for generic members. See the C# spec for details. 
    505441                         
    506                             # I cooked up the algorithm below as a quick way to fix some bugs caused by the previous implementation of um, doing nothing. 
    507                             # But this likely needs to be rewritten. 
    508                             candidates = [] 
    509  
    510                             # handle generic arguments to the method 
    511                             genericArgTypes = .genericArgTypes 
    512                             if genericArgTypes and genericArgTypes.count 
    513                                 members = List<of BoxMember>() 
    514                                 for member as BoxMember? in definition.members 
    515                                     if member inherits Method 
    516                                         if member.containsGenericParameters 
    517                                             if member.genericParams.count == genericArgTypes.count 
    518                                                 member = member.constructedMethodWith(genericArgTypes to !) 
    519                                             else 
    520                                                 member = nil 
    521                                     if member, members.add(member) 
    522                             else 
    523                                 members = definition.members 
    524  
    525                             for member in members 
    526                                 if member.params.count <> args.count 
    527                                     score = -1000 
    528                                 else 
    529                                     score = 0 
    530                                     i = 0 
    531                                     for param in member.params 
    532                                         arg = args[i] 
    533                                         if not arg.didBindImp 
    534                                             trace arg 
    535                                             trace arg.hasError 
    536                                         if arg.type == param.type 
    537                                             score += 20 
    538                                         else if arg.canBeAssignedTo(param.type) 
    539                                             score += 10 
    540                                         else if arg.type inherits NilableType and (arg.type to NilableType).theWrappedType.isAssignableTo(param.type)  
    541                                             # Cobra's code and data flow analysis sometimes leaves us with a nilable type that's not actually nil anymore 
    542                                             # due to an assignment, possibly wrapped in an if statement. Eventually this will be corrected, but for now 
    543                                             # compensate here. 
    544                                             score += 1 
    545                                         else 
    546                                             score -= 100 
    547                                         i += 1 
    548                                 # print 'candidate:', score, member.name, member.serialNum, Utils.join(', ', (for param in member.params get param.type.name)) 
    549                                 candidates.add([score, member]) 
    550                             maxScore = -10_000 
    551                             winner = nil to BoxMember? 
    552                             for pair in candidates 
    553                                 if pair[0] to int > maxScore 
    554                                     maxScore = pair[0] to int 
    555                                     winner = pair[1] to BoxMember 
    556                             if false 
    557                                 print 
    558                                 trace .token.fileName 
    559                                 trace maxScore, _name 
    560                                 trace .token.toTechString 
    561                                 trace winner 
    562                                 print 'args:' 
    563                                 for arg in args 
    564                                     print '   [arg]' 
    565                                 print 'params:' 
    566                                 for param in winner.params 
    567                                     print '   [param]' 
    568                                 print 'overloads:' 
    569                                 for member in definition.members 
    570                                     print '   [member]' 
    571                             # print 'winner:', score, winner 
     442                            winner = _calcBestOverload(definition, args) 
    572443                            sharp'definition = winner' 
    573444                            type = winner.resultType 
    574                         # end if definition inherits MemberOverload 
    575445                        else 
    576446                            type = definition.resultType 
    577                             hasVari = false 
    578                             for param in definition.params 
    579                                 if param.type inherits VariType, hasVari = true 
    580                             if hasVari 
    581                                 # TODO handle variable number of args (4) 
    582                                 pass 
    583                             else 
    584                                 if .genericArgTypes and .genericArgTypes.count 
    585                                     if definition inherits Method 
    586                                         definition = definition.constructedMethodWith(.genericArgTypes to !) 
    587                                         type = definition.resultType 
    588                                     else 
    589                                         .throwError('Cannot pass type arguments to "[definition.name]" because it is a [definition.getType.name].') # @@ _definition.englishName; also might need this error in other locations 
    590                                 check = true 
     447                            if not _didVariArgs(definition) 
     448                                definition = _chkGenerics(definition, inout type) 
    591449                                if not definition.hasParams 
    592                                     if .name == 'toString' 
    593                                         # HACK 
    594                                         # this enables someFloat.toString('0.0') 
    595                                         # can remove when primitives know their CLR types and look up their methods 
    596                                         pass 
    597                                     else if args.count 
    598                                         .throwError('The method "[definition.name]" is expecting 0 arguments, but [args.count] are being supplied in this call.') 
     450                                    _checkNoArgs(definition, args) 
    599451                                else 
    600452                                    params = definition.params 
    601                                     if args.count <> params.count 
    602                                         if _name=='toString'  # TODO because many structs like Decimal have a toString() overload which cannot currently be expressed in SystemInterfaces.cobra 
    603                                             check = false 
    604                                         else 
    605                                             .throwError('The method "[definition.name]" is expecting [params.count] argument[Utils.plural(params)], but [args.count] are being supplied in this call.') 
    606                                     if check 
    607                                         for i in args.count 
    608                                             arg = args[i] 
    609                                             param = params[i] 
    610                                             if arg.hasError 
    611                                                 break 
    612                                             if arg inherits AssignExpr  # assignments in arguments have special treatment 
    613                                                 break 
    614                                             assert arg.didBindImp, arg 
    615                                             assert param.didBindInt, param 
    616                                             if arg.canBeAssignedTo(param.type) 
    617                                                 arg.contextType = param.type 
    618                                             else 
    619                                                 if false 
    620                                                     print 
    621                                                     print '<> definition = [definition]' 
    622                                                     print '<> arg = ' stop 
    623                                                     arg.writeDeepString 
    624                                                     print '<> arg.type =', arg.type 
    625                                                     print '<> param = ' stop 
    626                                                     param.writeDeepString 
    627                                                     print '<> param.type =', param.type 
    628                                                     print '<> param.ifInheritsStack.count =', param.ifInheritsStack.count 
    629                                                 if arg.type inherits NilableType and not param.type inherits NilableType and (arg.type to NilableType).theWrappedType.isAssignableTo(param.type) 
    630                                                     .throwError('Argument [i+1] of method "[_name]" expects a non-nilable type ([param.type.name]), but the call is supplying a nilable type ([arg.type.name]).') 
    631                                                 else 
    632                                                     .throwError('Argument [i+1] of method "[_name]" expects type [param.type.name], but the call is supplying type [arg.type.name].') 
     453                                    if _checkParamsCount(definition, args, params) 
     454                                        _checkArgsAssignable(definition, args, params) 
    633455                else 
    634456                    throw FallThroughException(definition) 
    635             if type is nil 
    636                 type = .compiler.passThroughType 
     457            if type is nil, type = .compiler.passThroughType 
    637458            _definition = definition 
    638             if _definition 
    639                 _definition.isUsed = true 
     459            if _definition, _definition.isUsed = true 
    640460            _type = type 
    641461        assert _type, _definition 
    642462        if .args.count == 0 and .hasParens 
     
    647467                if arg inherits AssignExpr 
    648468                    .recordError('Cannot make assignments in arguments. This syntax is reserved in the future for keyword arguments.') 
    649469 
     470    ## helpers supporting _bindImp 
     471                 
     472    def _setGenericArgTypes 
     473        _genericArgTypes = List<of IType>() 
     474        num = 1 
     475        for typeProxy in _genericArgProxies 
     476            try 
     477                _genericArgTypes.add(typeProxy.realType) 
     478            catch ne as NodeException 
     479                ne.prefixMessage('For "[_name]" type arg [num]: ') 
     480                .compiler.recordError(ne) 
     481            num += 1 
     482        # TODO: Check types are compatible with call 
     483 
     484    def _transformEnumDecl(dotNode as DotExpr, enumDefi as EnumDecl) 
     485        # Foo.EnumType(MemberA, MemberB) 
     486        # Change to an EnumCallExpr 
     487        # Roll up Foo.Bar.Baz() into one EnumCallExpr 
     488        transformTarget = dotNode 
     489        while transformTarget.superNode inherits DotExpr 
     490            transformTarget = transformTarget.superNode to DotExpr 
     491        enumCall = EnumCallExpr(.token, _name, _args, enumDefi).bindImp 
     492        _type = enumCall.type to IType 
     493        transformTarget._transformTo(enumCall) 
     494 
     495    def _inferDefinitionAndType(dotNode as DotExpr, definition as INamedNode?, type as out IType?) as INamedNode? 
     496        type = nil 
     497        possibleDefinition = dotNode.left.memberForName(_name) 
     498        if possibleDefinition is nil 
     499            lrt = dotNode.left.receiverType 
     500            if lrt.isDynamic 
     501                type = .compiler.nilableDynamicType 
     502            else if lrt is .compiler.passThroughType 
     503                if _name == 'toString' 
     504                    type = .compiler.stringType 
     505                else 
     506                    type = .compiler.passThroughType 
     507            else 
     508                left = dotNode.left 
     509                suggs = left.suggestionsForBadMemberName(_name) 
     510                isBoxAccess = left inherits IdentifierExpr and (left to IdentifierExpr).definition inherits Box  # like "Console.writeLine" where the receiver is a literal class or struct reference 
     511                whoseTypeIs = if(isBoxAccess, '', ' whose type is "[left.receiverType.name]"') 
     512                .throwError('Cannot find a definition for "[_name]" in "[left.toCobraSource]"[whoseTypeIs].[_suggestionsMessage(suggs)]') 
     513        else 
     514            if not possibleDefinition.isCallable 
     515                .throwError('Cannot call "[_name]" because it is a "[possibleDefinition.englishName]".') 
     516            definition = possibleDefinition 
     517            type = possibleDefinition.resultType 
     518        return definition        
     519 
     520    def _transformIType(dotNode, definition as IType?) 
     521        # for Foo.Bar() where Bar is a box/type 
     522        # Change to a PostCallExpr on the type 'Foo.Bar' 
     523             
     524        # Roll up Foo.Bar.Baz() into one PostCallExpr 
     525        transformTarget = dotNode 
     526        while transformTarget.superNode inherits DotExpr 
     527            transformTarget = transformTarget.superNode to DotExpr 
     528                 
     529        postCall = PostCallExpr(.token, TypeExpr(.token, definition), .args).bindImp 
     530        _type = postCall.type to IType 
     531        transformTarget._transformTo(postCall) 
     532 
     533    def _bindImpArgs             
     534        num = 1 
     535        for arg in _args 
     536            try 
     537                if arg inherits AssignExpr 
     538                    arg.right.bindImp  # 'x=y' has special treatment in arguments 
     539                else 
     540                    arg.bindImp 
     541            catch ne as NodeException 
     542                ne.prefixMessage('For "[_name]" arg [num]: ') 
     543                .compiler.recordError(ne) 
     544            num += 1 
     545 
     546    def _calcBestOverload(definition as MemberOverload, args as List<of Expr>) as BoxMember 
     547        # I cooked up the algorithm below as a quick way to fix some bugs caused by the previous  
     548        # implementation of um, doing nothing. 
     549        # But this likely needs to be rewritten. 
     550        candidates = [] 
     551        # handle generic arguments to the method 
     552        genericArgTypes = .genericArgTypes 
     553        if genericArgTypes and genericArgTypes.count 
     554            members = List<of BoxMember>() 
     555            for member as BoxMember? in definition.members 
     556                if member inherits Method 
     557                    if member.containsGenericParameters 
     558                        if member.genericParams.count == genericArgTypes.count 
     559                            member = member.constructedMethodWith(genericArgTypes to !) 
     560                        else 
     561                            member = nil 
     562                if member, members.add(member) 
     563        else 
     564            members = definition.members 
     565 
     566        for member in members 
     567            score = -1000 
     568            if member.params.count == args.count 
     569                score = 0 
     570                i = 0 
     571                for param in member.params 
     572                    arg = args[i] 
     573                    if not arg.didBindImp 
     574                        trace arg 
     575                        trace arg.hasError 
     576                    if arg.type == param.type 
     577                        score += 20 
     578                    else if arg.canBeAssignedTo(param.type) 
     579                        score += 10 
     580                    else if arg.type inherits NilableType and (arg.type to NilableType).theWrappedType.isAssignableTo(param.type)  
     581                        # Cobra's code and data flow analysis sometimes leaves us with a nilable type that's not actually nil anymore 
     582                        # due to an assignment, possibly wrapped in an if statement. Eventually this will be corrected, but for now 
     583                        # compensate here. 
     584                        score += 1 
     585                    else 
     586                        score -= 100 
     587                    i += 1 
     588            # print 'candidate:', score, member.name, member.serialNum, Utils.join(', ', (for param in member.params get param.type.name)) 
     589            candidates.add([score, member]) 
     590 
     591        maxScore = -10_000 
     592        winner = nil to BoxMember? 
     593        for pair in candidates 
     594            if pair[0] to int > maxScore 
     595                maxScore = pair[0] to int 
     596                winner = pair[1] to BoxMember 
     597        if false 
     598            print 
     599            trace .token.fileName 
     600            trace maxScore, _name 
     601            trace .token.toTechString 
     602            trace winner 
     603            print 'args:' 
     604            for arg in args 
     605                print '   [arg]' 
     606            print 'params:' 
     607            for param in winner.params 
     608                print '   [param]' 
     609            print 'overloads:' 
     610            for member in definition.members 
     611                print '   [member]' 
     612        # print 'winner:', score, winner 
     613        assert winner 
     614        return winner to ! 
     615 
     616    def _didVariArgs(definition as BoxMember) as bool 
     617        hasVari = false 
     618        for param in definition.params 
     619            if param.type inherits VariType  
     620                hasVari = true 
     621        if hasVari 
     622            # TODO handle variable number of args (4) 
     623            return true 
     624        return false 
     625         
     626    def _chkGenerics(definition as BoxMember, type as inout IType?) as BoxMember 
     627        if .genericArgTypes and .genericArgTypes.count 
     628            if definition inherits Method 
     629                definition = definition.constructedMethodWith(.genericArgTypes to !) 
     630                type = definition.resultType 
     631            else 
     632                .throwError('Cannot pass type arguments to "[definition.name]" because it is a [definition.getType.name].') # @@ _definition.englishName; also might need this error in other locations 
     633        return definition 
     634                     
     635    def _checkNoArgs(definition as BoxMember, args as List<of Expr>) 
     636        if .name == 'toString' 
     637            # HACK 
     638            # this enables someFloat.toString('0.0') 
     639            # can remove when primitives know their CLR types and look up their methods 
     640            pass 
     641        else if args.count 
     642            .throwError('The method "[definition.name]" is expecting 0 arguments, but [args.count] are being supplied in this call.') 
     643     
     644    def _checkParamsCount(definition as BoxMember, args as List<of Expr>, params as List<of Param>) as bool 
     645        if args.count <> params.count 
     646            if _name=='toString'  # TODO because many structs like Decimal have a toString() overload which cannot currently be expressed in SystemInterfaces.cobra 
     647                return false 
     648            else 
     649                .throwError('The method "[definition.name]" is expecting [params.count] argument[Utils.plural(params)], but [args.count] are being supplied in this call.') 
     650        return true 
     651                 
     652    def _checkArgsAssignable(definition as BoxMember, args as List<of Expr>, params as List<of Param>)  
     653        for i in args.count 
     654            arg = args[i] 
     655            param = params[i] 
     656            if arg.hasError 
     657                break 
     658            if arg inherits AssignExpr  # assignments in arguments have special treatment 
     659                break 
     660            assert arg.didBindImp, arg 
     661            assert param.didBindInt, param 
     662            if arg.canBeAssignedTo(param.type) 
     663                arg.contextType = param.type 
     664            else 
     665                if false 
     666                    print 
     667                    print '<> definition = [definition]' 
     668                    print '<> arg = ' stop 
     669                    arg.writeDeepString 
     670                    print '<> arg.type =', arg.type 
     671                    print '<> param = ' stop 
     672                    param.writeDeepString 
     673                    print '<> param.type =', param.type 
     674                    print '<> param.ifInheritsStack.count =', param.ifInheritsStack.count 
     675                if arg.type inherits NilableType and not param.type inherits NilableType and (arg.type to NilableType).theWrappedType.isAssignableTo(param.type) 
     676                    .throwError('Argument [i+1] of method "[_name]" expects a non-nilable type ([param.type.name]), but the call is supplying a nilable type ([arg.type.name]).') 
     677                else 
     678                    .throwError('Argument [i+1] of method "[_name]" expects type [param.type.name], but the call is supplying type [arg.type.name].') 
     679    # end of _bindImp helpers 
     680         
    650681    def toCobraSource as String is override 
    651682        sb = StringBuilder() 
    652683        sb.append(_name) 
     
    10681099                # TODO 
    10691100                pass 
    10701101            else if _definition inherits Indexer 
    1071                 indexer = _definition 
    1072                 params = indexer.params 
    1073                 if args.count <> params.count 
    1074                     .throwError('The method "[_definition.name]" is expecting [params.count] argument[Utils.plural(params)], but [args.count] are being supplied in this call.') 
    1075                 for i = 0 .. args.count 
    1076                     arg = args[i] 
    1077                     param = params[i] 
    1078                     if arg.hasError 
    1079                         break 
    1080                     assert arg.didBindImp, arg 
    1081                     assert param.didBindInt, param 
    1082                     if arg.canBeAssignedTo(param.type) 
    1083                         arg.contextType = param.type 
    1084                     else 
    1085                         if false 
    1086                             print '<> arg = ' stop 
    1087                             arg.writeDeepString 
    1088                             print '<> param = ' stop 
    1089                             param.writeDeepString 
    1090                         if arg.type inherits NilableType and not param.type inherits NilableType and (arg.type to NilableType).theWrappedType.isAssignableTo(param.type) 
    1091                             .throwError('Argument [i+1] of indexer expects a non-nilable type ([param.type.name]), but the call is supplying a nilable type ([arg.type.name]).') 
    1092                         else 
    1093                             .throwError('Argument [i+1] of indexer expects type [param.type.name], but the call is supplying type [arg.type.name].') 
     1102                _bindImpIndexer(args, _definition) 
    10941103            else 
    10951104                throw FallThroughException(_definition) 
    10961105            _type = _definition.resultType 
    10971106            assert _type 
    1098  
     1107             
     1108    def _bindImpIndexer(args as List<of Expr>, indexer as Indexer) 
     1109        #indexer = _definition 
     1110        params = indexer.params 
     1111        if args.count <> params.count 
     1112            .throwError('The method "[_definition.name]" is expecting [params.count] argument[Utils.plural(params)], but [args.count] are being supplied in this call.') 
     1113        for i in 0 : args.count 
     1114            arg = args[i] 
     1115            param = params[i] 
     1116            if arg.hasError, break 
     1117            assert arg.didBindImp, arg 
     1118            assert param.didBindInt, param 
     1119            if arg.canBeAssignedTo(param.type) 
     1120                arg.contextType = param.type 
     1121            else 
     1122                if false 
     1123                    print '<> arg = ' stop 
     1124                    arg.writeDeepString 
     1125                    print '<> param = ' stop 
     1126                    param.writeDeepString 
     1127                if arg.type inherits NilableType and not param.type inherits NilableType and (arg.type to NilableType).theWrappedType.isAssignableTo(param.type) 
     1128                    .throwError('Argument [i+1] of indexer expects a non-nilable type ([param.type.name]), but the call is supplying a nilable type ([arg.type.name]).') 
     1129                else 
     1130                    .throwError('Argument [i+1] of indexer expects type [param.type.name], but the call is supplying type [arg.type.name].') 
     1131                         
    10991132    def toCobraSource as String is override 
    11001133        sb = StringBuilder() 
    11011134        sb.append(_target.toCobraSource) 
     
    12761309            .binarySuperNode.receiverType = receiverType 
    12771310             
    12781311            if _definition inherits BoxMember 
    1279                 # resolve overloads 
    1280                 if _definition inherits MemberOverload 
    1281                     for member in _definition.members 
    1282                         if member inherits AbstractMethod 
    1283                             if member.params.count == 0 
    1284                                 _definition = member 
    1285                                 didResolveOverload = true 
    1286                                 break 
    1287                     if not didResolveOverload 
    1288                         for member in (_definition to MemberOverload).members  # CC: shouldn't need cast 
    1289                             if member inherits AbstractMethod 
    1290                                 if member.params.count == 1 and member.params[0].type inherits VariType 
    1291                                     _definition = member 
    1292                                     didResolveOverload = true 
    1293                                     break 
    1294                     if not didResolveOverload 
    1295                         .throwError('Could not find an overload for "[.name]" with zero arguments.') 
    1296                 # check visibility: public, protected, private, internal 
    1297                 if _definition.isPublic 
    1298                     pass 
    1299                 else if _definition.isProtected 
    1300                     if not .compiler.curBox.isDescendantOf(_definition.parentBox) 
    1301                         whoseTypeIs = if(isBoxAccess, '', ' whose type is "[left.receiverType.name]"') 
    1302                         .throwError('Cannot access protected "[_name]" in "[left.toCobraSource]"[whoseTypeIs].') 
    1303                 else if _definition.isPrivate 
    1304                     if not .compiler.curBox is _definition.parentBox 
    1305                         whoseTypeIs = if(isBoxAccess, '', ' whose type is "[left.receiverType.name]"') 
    1306                         .throwError('Cannot access private "[_name]" in "[left.toCobraSource]"[whoseTypeIs].') 
    1307                 else if _definition.isInternal 
    1308                     # TODO 
    1309                     pass 
     1312                _bindImpBoxMember(_definition, isBoxAccess, left)           # resolve overloads 
    13101313            else 
    13111314                # TODO: type access like enum, class, delegate 
    13121315                pass 
    13131316        assert _type 
    13141317 
     1318    def _bindImpBoxMember(defn as BoxMember, isBoxAccess as bool, left as Expr) 
     1319        # resolve overloads 
     1320        if defn inherits MemberOverload 
     1321            for member in defn.members 
     1322                if member inherits AbstractMethod 
     1323                    if member.params.count == 0 
     1324                        _definition = member 
     1325                        didResolveOverload = true 
     1326                        break 
     1327            if not didResolveOverload 
     1328                for member in defn.members  
     1329                    if member inherits AbstractMethod 
     1330                        if member.params.count == 1 and member.params[0].type inherits VariType 
     1331                            _definition = member 
     1332                            didResolveOverload = true 
     1333                            break 
     1334            if not didResolveOverload 
     1335                .throwError('Could not find an overload for "[.name]" with zero arguments.') 
     1336        # check visibility: public, protected, private, internal 
     1337        if defn.isPublic 
     1338            pass 
     1339        else if defn.isProtected 
     1340            if not .compiler.curBox.isDescendantOf(defn.parentBox) 
     1341                whoseTypeIs = if(isBoxAccess, '', ' whose type is "[left.receiverType.name]"') 
     1342                .throwError('Cannot access protected "[_name]" in "[left.toCobraSource]"[whoseTypeIs].') 
     1343        else if defn.isPrivate 
     1344            if not .compiler.curBox is defn.parentBox 
     1345                whoseTypeIs = if(isBoxAccess, '', ' whose type is "[left.receiverType.name]"') 
     1346                .throwError('Cannot access private "[_name]" in "[left.toCobraSource]"[whoseTypeIs].') 
     1347        else if defn.isInternal 
     1348            # TODO 
     1349            pass 
     1350             
    13151351    def toCobraSource as String is override 
    13161352        return _name 
    13171353 
  • Source/CobraTokenizer.cobra

     
    880880        throw Exception('ordered token') 
    881881 
    882882    def match(input as String) as TokenMatch? is override 
    883         s = ._match(input) 
     883        s = _match(input) 
    884884        if s 
    885885            return TokenMatch(s) 
    886886        else 
  • Source/CobraParser.cobra

     
    18321832                _statementsFor(codePart) 
    18331833        finally 
    18341834            _popCodePart 
    1835  
     1835            # warn on horrendously long methods, enabling this and cutoff should be user configurable 
     1836            if true and codePart.statements.count >0 
     1837                startline = codePart.statements[0].token.lineNum 
     1838                nLines = codePart.statements[codePart.statements.count-1].token.lineNum - startline +1 
     1839                pName = '[codePart.parentBox.name].[codePart.name]' 
     1840                if nLines > 100 
     1841                    _warning("More than 100 Lines of Code ([codePart.statements.count] toplevel statements) in method [pName]")  
     1842                #print '[pName.padLeft(50)]\t[nLines]\t[codePart.statements.count]' 
     1843                     
    18361844    def _statementsFor(codePart as AbstractMethod) 
    18371845        """ 
    18381846        Utility method for .statementsFor.