Wiki

Ticket #151: vari-typed-params.patch

File vari-typed-params.patch, 6.6 KB (added by hopscc, 12 years ago)
  • Source/Expr.cobra

     
    727727                            #/ 
    728728                        else 
    729729                            type = definition.resultType 
    730                             if not _didVariArgs(definition) 
     730                            if _didVariArgs(definition) 
     731                                params = definition.params 
     732                                _checkArgsAssignable(definition, args, params) 
     733                            else 
    731734                                definition = _checkGenerics(definition, inout type) 
    732735                                if not definition.hasParams 
    733736                                    _checkNoArgs(definition, args) 
     
    736739                                    if _checkParamsCount(definition, args, params) 
    737740                                        if needInferOutArgs, _inferOutArgs(args, params, false)  
    738741                                        _checkArgsAssignable(definition, args, params) 
     742                                 
    739743                        _checkInOutArguments 
    740744                        _checkVisibility(definition, dotNode.left) 
    741745                else 
     
    896900        for i in args.count 
    897901            arg = args[i] 
    898902            param = params[i] 
    899             if param.type inherits VariType, break  # to-do: vari args not checked yet 
    900             if arg.hasError 
     903            if arg.hasError  
    901904                break 
    902905            if arg inherits AssignExpr  # assignments in arguments have special treatment 
    903906                break 
     907            if param.type inherits VariType  
     908                _checkVariArgsAssignable(args, params, i, arg, param) 
     909                break    
    904910            assert arg.didBindImp 
    905911            assert param.didBindInt 
    906912            # check any in/out/inout expectations are matched 
     
    929935                else 
    930936                    arg.recordError('Argument [i+1] of method "[_name]" expects type [param.type.name], but the call is supplying type [arg.type.name].') 
    931937 
     938    def _checkVariArgsAssignable(args as IList<of Expr>, params as IList<of Param>, ofset as int, arg as Expr, param as Param) 
     939        require param.type inherits VariType  
     940        variType = param.type.innerType to ! 
     941        typeName = param.type.name 
     942        if typeName.startsWith('vari Object') or typeName.startsWith('vari dynamic')  # always assignable 
     943            return 
     944        argPos = ofset+1 
     945        if args.count == argPos and arg.canBeAssignedTo(variType) #single arg for last vari param 
     946            return 
     947        if variType inherits ArrayType  # library variType is Array 
     948            variArrayType = variType.innerType to ! 
     949            if arg.canBeAssignedTo(variArrayType) 
     950                return 
     951        if arg.canBeAssignedTo(param.type) # variType and array 
     952            arg.contextType = param.type 
     953            return 
     954        if args.count <> params.count # variType and arg list 
     955            t = arg.type 
     956            for i in ofset+1 : args.count 
     957                t = t.greatestCommonDenominatorWith(args[i].type to !) 
     958            if t.isAssignableTo(variType) 
     959                return 
     960            arg.recordError(_variArgsErrorMsg(t to !,  param.type, argPos, true))        
     961            return 
     962        arg.recordError(_variArgsErrorMsg(arg.type to !, param.type, argPos, false))         
     963                     
     964    def _variArgsErrorMsg(argType as IType, paramType as IType, argPos as int, withArgList as bool) as String        
     965        targetMsg = if(withArgList, ' an arglist resolving to', '') 
     966        if argType inherits NilableType and not paramType inherits NilableType 
     967            msg = 'Vari argument [argPos] of method "[_name]" expects a non-nilable type ([paramType.name]), but the call is supplying[targetMsg] a nilable type ([argType.name]).' 
     968        else 
     969            msg = 'Vari argument [argPos] of method "[_name]" expects type [paramType.name], but the call is supplying [targetMsg] type [argType.name].' 
     970        return msg 
     971         
    932972    def _toErrorPhrase(d as Direction) as String 
    933973        branch d 
    934974            on Direction.In, return 'a regular' 
  • Source/CommandLine.cobra

     
    575575        return ver 
    576576 
    577577    get opSysString as String is shared 
    578         # to-do: after next compiler snapshot, replace this with CobraCore.operatingSystemDescription 
    579         name = '' 
    580         if File.exists('/System/Library/CoreServices/SystemVersion.plist') 
    581             # Mac 
    582             content = File.readAllText('/System/Library/CoreServices/SystemVersion.plist') 
    583             match = Regex.match(content, r'<string>(Mac[^<]+)') 
    584             if match.success 
    585                 name += match.groups[1].toString 
    586             match = Regex.match(content, r'<string>(\d+\.[\d\.]+)') 
    587             if match.success 
    588                 name += ' ' + match.groups[1].toString 
    589         else if File.exists('/etc/lsb-release') 
    590             # Ubuntu, ... 
    591             content = File.readAllText('/etc/lsb-release') 
    592             d = Dictionary<of String, String>() 
    593             for line in content.splitLines 
    594                 line = line.trim 
    595                 if line == '' or line.startsWith('#') or '=' not in line, continue 
    596                 pair = line.split('=', 2) 
    597                 d[pair[0].trim] = pair[1].trim 
    598             if d.containsKey('DISTRIB_DESCRIPTION'), name = d['DISTRIB_DESCRIPTION'].trim 
    599             if name == '' 
    600                 try 
    601                     name = d['DISTRIB_ID'] + ' ' + d['DISTRIB_RELEASE'] 
    602                 catch 
    603                     pass 
    604             if name.startsWith('"') and name.endsWith('"'), name = name[1:-1] 
    605         else if File.exists('/etc/arch-release') 
    606             # Arch Linux 
    607             name = 'Arch Linux ' + _getCommandOutput('/bin/uname', '-r').trim 
    608             pacman = _getCommandOutput('pacman', '--version') 
    609             match = Regex.match(pacman, r'[Pp]acman v?(\d+\.[\d\.]+)') 
    610             if match.success 
    611                 name += ' (pacman ' + match.groups[1].toString.trim + ')' 
    612         else if File.exists('/etc/system-release') 
    613             # CentOS, Fedora, ... 
    614             name = File.readAllText('/etc/system-release') 
    615         else if File.exists('/etc/redhat-release') 
    616             # RedHat, ... 
    617             name = File.readAllText('/etc/redhat-release') 
    618         name = name.trim 
    619         if name == '' 
    620             # everyone else 
    621             name = Environment.osVersion.toString 
    622         return name 
     578        return CobraCore.operatingSystemDescription 
    623579 
    624580    def _getCommandOutput(command as String, args as String) as String is shared 
    625581        p = System.Diagnostics.Process() 
  • Tests/800-warnings/600-vari-nilable-pars.cobra

     
     1class Test 
     2 
     3    def takesVari(x as vari String) is shared 
     4        for y in x 
     5            print y 
     6 
     7    def takesVariNil(x as vari String?) is shared 
     8        for y in x 
     9            print y 
     10 
     11    def takesArray(x as String[]) is shared 
     12        for y in x 
     13            print y 
     14         
     15    def foo(args as vari int) as int is shared 
     16        sum = 0 
     17        for arg in args, sum += arg 
     18        return sum 
     19         
     20    def main is shared 
     21         
     22        .takesVari('hola', nil)     # .error. expects a non-nilable  
     23        .takesVari(@['hola', nil])  # .error. expects type vari String 
     24 
     25        #.takesArray(@['hola', nil])  #Argument 1 expects type String[], but supplying type String?[] 
     26         
     27        .takesVari('hola', 'nonnil') 
     28        .takesVariNil('hola', nil) 
     29         
     30        x = .foo(1,2) 
     31        assert x == 3 
     32        x = .foo(1) 
     33        assert x == 1