Wiki

Ticket #201: use-aliases.patch

File use-aliases.patch, 8.0 KB (added by hopscc, 13 years ago)
  • Source/Phases/BindUsePhase.cobra

     
    5959 
    6060 
    6161class UseDirective is partial 
    62  
    6362    get didBindUse from var as bool 
    6463 
    6564    def bindUse 
     
    8786            # curNS = nil # force reference attempt 
    8887        if curNS is nil and not didAutoLoad 
    8988            if _fileName <> '' 
    90                 if .compiler.loadReference(_fileName + '.dll') 
    91                     _bindUse(true) 
    92                     if .boundNameSpace is nil 
    93                         .throwError('Cannot find namespace "[_fullName]" in library "[_fileName]".') 
     89                if _loadReferenceInFile(_fileName, _fullName, ignoreError) 
    9490                    return 
    95                 else 
    96                     if ignoreError 
    97                         _bindUse(true) 
    98                         return 
    99                     .throwError('Cannot find library file "[_fileName]".') 
     91                .throwError('Cannot find library file "[_fileName]".') 
    10092            else 
    10193                if _fullName.endsWith('.dll') 
    10294                    .throwError('Do not end a namespace name in a "use" directive with ".dll".') 
    103                 if .compiler.loadReference(_fullName + '.dll') 
    104                     _bindUse(true) 
    105                     if .boundNameSpace is nil 
    106                         .throwError('Cannot find namespace "[_fullName]" in loaded library "[_fullName]".') 
     95                if _loadReferenceInFile(_fullName, _fullName, ignoreError) 
    10796                    return 
     97                # load fail, not found 
     98                # compute how far is valid, but only here where it's needed for the error message 
     99                partialName = '' 
     100                curNS = .compiler.globalNS to ? 
     101                for name in _nameParts 
     102                    curNS = curNS.subNameSpaceForName(name) 
     103                    if curNS is nil, break 
     104                    partialName += '.' + name 
     105                if partialName == '' 
     106                    .throwError('Cannot find namespace "[_fullName]".') 
    108107                else 
    109                     if ignoreError 
    110                         _bindUse(true) 
    111                         return 
    112                     # compute how far is valid, but only here where it's needed for the error message 
    113                     partialName = '' 
    114                     curNS = .compiler.globalNS to ? 
    115                     for name in _nameParts 
    116                         curNS = curNS.subNameSpaceForName(name) 
    117                         if curNS is nil, break 
    118                         partialName += '.' + name 
    119                     if partialName == '' 
    120                         .throwError('Cannot find namespace "[_fullName]".') 
    121                     else 
    122                         .throwError('Cannot find namespace "[name]" in "[partialName[1:]]".') 
     108                    .throwError('Cannot find namespace "[name]" in "[partialName[1:]]".') 
    123109        if not didAutoLoad 
    124110            assert curNS, 'last name=[name]; [_nameParts]; [_fullName]; [_fileName]' 
    125111        _boundNameSpace = curNS 
    126112        _didBindUse = true 
     113         
     114    def _loadReferenceInFile(filename as String, nameSpace as String, ignoreError as bool) as bool 
     115        if .compiler.loadReference(filename + '.dll') 
     116            _bindUse(true) 
     117            if .boundNameSpace is nil 
     118                .throwError('Cannot find namespace "[nameSpace]" in library "[filename]".') 
     119            return true 
     120        else 
     121            if ignoreError 
     122                _bindUse(true) 
     123                return true 
     124        # cant find reference in filename.dll, Is it an alias to a class? 
     125        if _alias.length and _setAliasSymbol     
     126            return true 
     127        return false         
     128 
     129    def _setAliasSymbol as bool 
     130        """ 
     131        Processing of an alias for item in a Namespace. 
     132        Try this UseDirective as an alias to a class (Box) in a Namespace. 
     133        If the nameParts path is loadable and the final nameParts part exists in it 
     134        Save the reference as the aliasSymbol. 
     135        """ 
     136        nameParts = _nameParts 
     137        _nameParts = nameParts[0:-1]    # nameParts path not including last part 
     138        possNS = _nameParts.join('.') 
     139        if .compiler.loadReference(possNS + '.dll') 
     140            _bindUse(true) 
     141            if .boundNameSpace  
     142                # got a namespace, look for symbol in it 
     143                symName = nameParts[nameParts.count-1]  # last part 
     144                s = .boundNameSpace.symbolForName(symName) 
     145                if s  
     146                    _aliasSymbol = s 
     147                    return true  
     148                _nameParts = nameParts 
     149            else 
     150                _nameParts = nameParts 
     151                .throwError('Cannot find namespace "[possNS]".') 
     152        return false         
  • Source/NameSpace.cobra

     
    376376    var _nameParts as List<of String> 
    377377    var _boundNameSpace as NameSpace? 
    378378    var _fullName as String 
     379    var _alias as String 
     380    var _aliasSymbol as IMember? 
    379381    var _fileName as String 
    380382    var _explicitUses as bool 
    381383 
    382384    cue init(token as IToken, nameParts as List<of String>) 
    383         .init(token, nameParts, '', false) 
     385        .init(token, nameParts, '', false, nil) 
    384386 
    385387    cue init(token as IToken, nameParts as List<of String>, fileName as String?) 
    386         .init(token, nameParts, fileName, false) 
     388        .init(token, nameParts, fileName, false, nil) 
    387389 
    388     cue init(token as IToken, nameParts as List<of String>, fileName as String?, explicitUses as bool) 
     390    cue init(token as IToken, nameParts as List<of String>, fileName as String?, explicitUses as bool, alias as String?) 
    389391        base.init(token) 
    390392        _nameParts = nameParts 
    391393        _fullName = nameParts.join('.') 
    392394        _fileName = fileName ? '' 
    393395        _explicitUses = explicitUses 
    394  
     396        _alias = alias ? '' 
     397         
    395398    def addMinFields 
    396399        base.addMinFields 
    397400        .addField('fullName', _fullName) 
     
    410413 
    411414    def findSymbol(name as String) as IMember? 
    412415        require .didBindUse 
     416        if name == _alias, return _aliasSymbol ? _boundNameSpace 
    413417        return _boundNameSpace.symbolForName(name) 
  • Source/CobraParser.cobra

     
    495495        Example source: 
    496496            use System.Net 
    497497            use Foo 
     498            use Wrapper.Console as WrCons # alias  
    498499        """ 
    499500        token = .expect('USE') 
    500501        names = List<of String>() 
     
    503504            names.add(id.text) 
    504505            dot = .optional('DOT') 
    505506            if not dot, break 
     507        if .optional('AS') 
     508            alias = .expect('ID').text  # unqualified string 
    506509        if .optional('FROM') 
    507510            if .peek.which.startsWith('STRING_') and not .peek.which.startsWith('STRING_START') 
    508511                fileName = .grab.value to String 
     
    519522            if fileName.endsWith('.dll') or fileName.endsWith('.exe') 
    520523                .throwError('Do not include the extension in the file name.') 
    521524        .endOfLine 
    522         return UseDirective(token, names, fileName, true) 
     525        return UseDirective(token, names, fileName, true, alias) 
    523526 
    524527    var _syntaxForClassInheritanceMsg = 'The syntax for inheritance is to put "inherits BaseClass" on the following line, indented.' 
    525528 
  • Tests/720-libraries/400-other/240-use-with-alias.cobra

     
     1# Test use with an alias for a namespace 
     2 
     3use System.Text.RegularExpressions as RE 
     4 
     5class AliasUse 
     6    def main is shared 
     7        s='foo bar\nbaz\r\nfroob\twap' 
     8        re = RE.Regex(r'\s+') 
     9        assert re.split(s).toList == ['foo', 'bar', 'baz', 'froob', 'wap'] 
     10         
  • Tests/720-libraries/400-other/242-use-with-alias-class.cobra

     
     1# Test use with alias for a Box/class within a namespace 
     2use System.Console as Cons 
     3#use System as Sys 
     4use Cobra.Lang.CobraCore as CC 
     5 
     6class Test 
     7    def main is shared 
     8#       Sys.Console.writeLine('Hello there folks') 
     9        Cons.writeLine('Hi mike') 
     10        v = CC.version 
     11        v1 = CobraCore.version 
     12        assert v == v1 
  • Tests/720-libraries/400-other/214-use-lib-with-no-ref-ns-not-found-error.cobra

     
    11 
    2 use Foo.Mismatch # .error. Cannot find namespace "Foo.Mismatch" in loaded library "Foo.Mismatch" 
     2use Foo.Mismatch # .error. Cannot find namespace "Foo.Mismatch" in library "Foo.Mismatch" 
    33 
    44class X 
    55