Wiki

Ticket #39: ref-type-inference.patch

File ref-type-inference.patch, 27.0 KB (added by hopscc, 7 years ago)
  • Source/Expr.cobra

     
    18551855            throw 
    18561856        finally 
    18571857            .compiler.refExprLevel -= 1 
     1858        _checkRefExpr    
     1859        _type = .compiler.passThroughType # something if refSig make signature fails 
     1860        refSig = _makeSignatureOfExpr 
     1861        if refSig 
     1862            refSig.bindInh 
     1863            refSig.bindInt 
     1864            refSig.bindImp 
     1865            container = .compiler.curCodeMember.parentBox 
     1866            compatSig = container.sigForMethodSig(refSig) 
     1867            _type = compatSig ? refSig 
     1868            if not compatSig 
     1869                msg = 'No signature matching the signature of "[_expr.definition.name]" ([refSig.toCobraSource]) in the inheritance tree or used namespaces.' 
     1870                sugg = 'Did you leave out a sig statement in scope for this method reference?' 
     1871                action = 'Adding generated sig "[refSig.toCobraSource]" to [container.name]' 
     1872                .compiler.warning(this, '[msg]  [sugg]\n[action]') 
     1873                container.addDecl(refSig) 
     1874                 
     1875    def _checkRefExpr    
    18581876        if _expr inherits DotExpr 
    18591877            right = _expr.right 
    18601878            if right inherits MemberExpr 
     
    18701888            else 
    18711889                throw FallThroughException([this, _expr, right]) 
    18721890        else if _expr inherits IdentifierExpr 
    1873             if _expr.definition inherits AbstractMethod 
    1874                 pass 
    1875             else 
     1891            if not ( _expr.definition inherits AbstractMethod ) 
    18761892                .throwError('Only methods can be referenced, not [Utils.pluralize(_expr.definition.englishName)].') 
    18771893        else 
    18781894            .throwError('Unexpected reference. Refer to methods after `ref` or remove `ref`.') 
    1879         _type = .compiler.passThroughType # TODO: Set a real type such as .compiler.delegateType 
    1880         # TODO: need to do something more sophisticated like overriding:    def canBeAssignedTo(type as IType) as bool 
    1881  
     1895             
     1896    def _makeSignatureOfExpr as MethodSig? 
     1897        """Auto generate a signature for type of expression being 'ref'd"""  
     1898        if _expr inherits DotExpr 
     1899            right = _expr.right 
     1900            if right inherits MemberExpr 
     1901                if right.definition inherits AbstractMethod  
     1902                    am = right.definition to AbstractMethod 
     1903                    signature = _makeSig(am, _expr.right.token) 
     1904                else if right.definition inherits MemberOverload 
     1905                    mo = right.definition to MemberOverload 
     1906                    if mo.members[0] inherits AbstractMethod 
     1907                        am = mo.members[0] to AbstractMethod  
     1908                        signature = _makeSig(am, _expr.right.token) 
     1909        else if _expr inherits IdentifierExpr 
     1910            if _expr.definition inherits AbstractMethod 
     1911                am = _expr.definition to AbstractMethod 
     1912                signature = _makeSig(am, _expr.token) 
     1913        return signature 
     1914             
     1915    def _makeSig(am as AbstractMethod, token as IToken) as MethodSig 
     1916        """Make an (anonymously named) signature corresponding to the provided method""" 
     1917        sigToken= token.copy('ID', 'sigForRef')  
     1918        nameToken = token.copy  
     1919        container = .compiler.curCodeMember.parentBox 
     1920        name = 'SigFor_'+nameToken.value to String 
     1921        isNames = List<of String>() 
     1922        attribs = AttributeList() 
     1923        docString = '' to ? 
     1924        returnType = am.resultType 
     1925        params     = List<of Param>(am.params) 
     1926        return MethodSig(sigToken, nameToken, container, name, params, returnType, isNames, attribs, docString) 
     1927         
    18821928    def toCobraSource as String is override 
    18831929        return 'ref ' + _expr.toCobraSource 
    18841930 
  • Source/BackEndClr/ScanClrType.cobra

     
    5555                    if type.isClass 
    5656                        if type.name.startsWith('Extend_') and type.name.count(c'_') >= 2 
    5757                            curNameSpace.addDecl(Extension(clrType)) 
     58                        else if _shouldBeMethodSig(type) 
     59                            #print curNameSpace.name, type.name  
     60                            curNameSpace.addDecl(MethodSig(clrType)) 
    5861                        else 
    5962                            curNameSpace.addDecl(Class(clrType)) 
    6063                    else if type.isInterface 
     
    7073                        throw FallThroughException(type) 
    7174        finally 
    7275            _curModule = saveModule 
     76             
     77    def _shouldBeMethodSig(type as Type) as bool 
     78        if not type.isSubclassOf(System.MulticastDelegate) 
     79            return false 
     80        #if type.isGenericType 
     81        #   print type.namespace, type.name  
    7382 
     83        # Below delegates are generic types in System that are 'too' general re params and return types 
     84        # and give 'false' matches for simple common cases (min params and (no) return types) 
     85        # so we suppress them.  
     86        #Inferred uses will probably either need an explicit compatible signature or will get a warning generated... 
     87        if type.name in ['CrossAppDomainDelegate', 'Converter`2', 'Action`1', 'EventHandler`1'] 
     88            return false    # other possible candidates include Predicate`1  
     89        return true 
     90             
    7491    def fixNilableMemberSigs 
    7592        # TODO: this really needs to go in a separate file that the compiler reads each time 
    7693 
     
    465482 
    466483    def _memberTypeProxy(clrType as Type?, notNullAttr as bool) as ITypeProxy 
    467484        """ 
    468         Returns a type proxy for a member type such as a parameter type or method return type. 
     485        Returns a type proxy for a member type such as a parameter type or member type. 
    469486        In CLR, reference types are nilable by default, but you can pass `true` for `notNullAttr` to indicate there was a NotNullAttribute in the DLL. 
    470487        """ 
    471488        if clrType is nil 
     
    481498 
    482499    def _memberTypeResultProxy(member as MemberInfo, clrType as Type?) as ITypeProxy 
    483500        """ 
    484         Returns a type proxy for a member type such as a parameter type or method return type. 
     501        Returns a type proxy for a member result type such as a property or field type or method return type. 
    485502        In CLR, reference types are nilable by default. 
    486503        """ 
    487         if clrType is nil 
     504        if clrType is nil or clrType is sharp'typeof(void)' # C# null data vs null code return 
    488505            return .compiler.voidType 
    489506        else if clrType.isValueType 
    490507            return ClrTypeProxy(clrType) 
     
    571588        # the first argument is implicit in an Extension 
    572589        results = base._scanParams(paramInfos) 
    573590        return results[1:] 
     591         
     592class MethodSig  
     593    is partial 
     594     
     595    def _scanNativeType 
     596        base._scanNativeType 
     597        _scanIsNames 
     598        #_scanImplements 
     599        #_scanNestedTypes 
     600        #_scanFields 
     601        _scanInitializers 
     602        #_scanProperties 
     603        _scanMethods 
     604        #_scanEvents 
     605         
     606        # reflect on  invoke method to find signature 
     607        methInfo = .clrType.getMethod('Invoke', BindingFlags(Instance, Static, DeclaredOnly, Public, NonPublic)) 
     608        if methInfo and _methOK(methInfo to !) 
     609            _params = _scanParams(methInfo.getParameters) 
     610            _returnTypeProxy = _memberTypeResultProxy(methInfo to !, methInfo.returnType)  
     611        #if .clrType.isGenericType 
     612        #   print .name, methInfo.returnType, _params 
     613                 
     614    def _methOK( methInfo as System.Reflection.MethodInfo)  as bool 
     615        if methInfo.isSpecialName or methInfo.isAssembly or methInfo.isPrivate 
     616            return false 
     617        if methInfo.declaringType is not .clrType, return false 
     618        if  _badRelatedType(methInfo.returnType) 
     619            return false 
     620        for paramInfo in methInfo.getParameters 
     621            if _badRelatedType(paramInfo.parameterType) 
     622                return false 
     623        return true      
  • Source/Boxes.cobra

     
    417417            _declsByName[ol.name] = ol 
    418418            _declsByNameCI[ol.name.toLower] = ol 
    419419 
     420    def addDecl(decl as IBoxMember) is override 
     421        base.addDecl(decl) 
     422        # overridden to explicitly store methodSigs separately 
     423        if decl inherits MethodSig 
     424            base.addSig(decl) 
     425 
    420426    def addDeclFromOverload(decl as IBoxMember, ol as MemberOverload) 
    421427        require 
    422428            ol in .overloads 
     
    15011507    The "sig" keyword fits nicely with other declaration keywords like "var" "def" and "get". 
    15021508    And "sig" is a more platform neutral term should we have other non-CLI backends. 
    15031509     
    1504     MethodSigs are only created when parsing. When reading from a DLL, delegates are merely 
    1505     subclasses of Delegate or MulticastDelegate. 
     1510    MethodSigs are created when parsing. When reading from a DLL, delegates are merely 
     1511    subclasses of (class) Delegate but subclasses of MulticastDelegate are created as MethodSigs so that 
     1512    type inference and sig matching can be done if such a MethodSig is used as a type.. 
    15061513     
    15071514    Note that MethodSig is a subclass of Class and therefore both a Box and an IType. Also, it will 
    15081515    return true for .isDescendantOf(.compiler.delegateType). 
     
    15201527        _params = params 
    15211528        _returnTypeProxy = returnTypeProxy 
    15221529  
     1530    cue init(nativeType as NativeType) 
     1531        base.init(TokenFix.empty, TokenFix.empty, ClrTypeProxy.cobraNameForSharpBoxName(nativeType.name), 
     1532            List<of IType>(), List<of String>(), AttributeList(),  
     1533            LibraryTypeProxy('System.MulticastDelegate'), List<of ITypeProxy>(),  
     1534            List<of ITypeProxy>(), nil) 
     1535        _initNativeType(nativeType) 
     1536        # below are temp placeholders until _scanNativeType runs (no params, void returned) 
     1537        _params = List<of Param>() 
     1538        _returnTypeProxy = TypeProxy(.compiler.voidType) 
     1539 
    15231540    get params from var 
    15241541     
    15251542    get returnTypeProxy from var 
     
    15291546    get resultType as IType? is override 
    15301547        return .returnType 
    15311548 
     1549    def addRefFields 
     1550        base.addRefFields 
     1551        .addField('params', _params) 
     1552        .addField('returnType', _returnType) 
     1553         
    15321554    def _bindInh 
    15331555        base._bindInh 
    15341556        assert _baseClass 
    15351557        assert _baseClass.qualifiedName == 'System.MulticastDelegate' 
    15361558        assert .parentBox or .parentNameSpace 
    1537  
     1559        assert not _needScanNativeType 
     1560         
    15381561    def _bindInt 
    1539         returnType as ITypeProxy = .returnType ? .returnTypeProxy 
    1540         .addDecl(_makeMethod('invoke', .params.clone, returnType)) 
    1541         # dynamic type vari length param in list as placeholder for multiple params  
    1542         params = [Param('vParam', VariTypeIdentifier(.token, TypeIdentifier(.token, DynamicType())))] 
    1543         .addDecl(_makeMethod('beginInvoke', params, TypeIdentifier(.token.copy('ID', 'IAsyncResult')) to ITypeProxy)) 
    1544         .addDecl(_makeMethod('endInvoke',   params, returnType )) 
     1562        if not .isFromBinaryLibrary # If From Assembly/Library these methods have already been inserted  
     1563            # TODO: push these down to _ScanClrType, platform specific. 
     1564            returnType as ITypeProxy = .returnType ? .returnTypeProxy 
     1565            .addDecl(_makeMethod('invoke', .params.clone, returnType)) 
     1566            # dynamic type vari length param in list as placeholder for multiple params  
     1567            params = [Param('vParam', VariTypeIdentifier(.token, TypeIdentifier(.token, DynamicType())))] 
     1568            .addDecl(_makeMethod('beginInvoke', params, TypeIdentifier(.token.copy('ID', 'IAsyncResult')) to ITypeProxy)) 
     1569            .addDecl(_makeMethod('endInvoke',   params, returnType )) 
    15451570        base._bindInt 
    15461571        for param in .params 
    15471572            param.bindInt 
     
    15561581        # method body just to avoid a Cobra warning during .bindImp 
    15571582        m.statements.add(ThrowStmt(.token, PostCallExpr(.token, IdentifierExpr(.token, 'Exception'), List<of Expr>())))  
    15581583        return m 
     1584     
     1585    def isAssignableTo(type as IType) as bool is override 
     1586        r = base.isAssignableTo(type) 
     1587        if not r 
     1588            if (nnt = type.nonNil) inherits MethodSig 
     1589                r = .isAnonymousMatch(nnt) 
     1590        return r 
     1591             
     1592    def isAnonymousMatch(aSig as MethodSig) as bool 
     1593        """ 
     1594        Indicate whether this methodSig is an anonymous match for the provided one. 
     1595        An anonymous match is one that ignores the name but succeeds if the sig returnType and 
     1596        the count, type and ordering of the parameters is the same. 
     1597        """ 
     1598        if .isFromBinaryLibrary  
     1599            # if from platform Assembly/Library do (minimal) bindings on-demand   
     1600            if not .didBindInh, .bindInh # TODO: optimise this more 
     1601            if not .didBindInt, .bindInt     
     1602        assert aSig.returnType 
     1603        assert .returnType 
     1604        #print '    [aSig.name] [.name] ReturnType', aSig.returnType.name, .returnType.name 
     1605        if not _matchesType(aSig.returnType to !, .returnType to !) 
     1606            return false 
     1607        params = .params 
     1608        otherParams = aSig.params 
     1609        #print '    ParamCount',  otherParams.count, params.count 
     1610        if otherParams.count <> params.count 
     1611            return false 
     1612        for i in params.count 
     1613            #print '    param([i])',  otherParams[i].type.name, params[i].type.name, otherParams[i].type, params[i].type 
     1614            if not _matchesType(otherParams[i].type, params[i].type) 
     1615                return false 
     1616            if otherParams[i].direction <> params[i].direction 
     1617                return false 
     1618        return true 
     1619 
     1620    def _matchesType(a as IType, b as IType) as bool 
     1621        if a.nonNil inherits GenericParam or b.nonNil inherits GenericParam 
     1622            return true 
     1623        # The above provides a mixed blessing of matches to generic delegates (delegates with generic params)  
     1624        # of which in 'use'ed assemblies (System specifically) there are a bunch that match common cases.  
     1625        # Good for Comparable implementations, erroneous hits for pretty much every other simple signature 
     1626        # See ScanClrType for how this is addressed. 
     1627        return a.isAssignableTo(b) # is this sufficient? 
     1628     
     1629    def toCobraSource as String 
     1630        s = StringBuilder() 
     1631        s.append('sig ' + .name ) 
     1632        if .params.count 
     1633            s.append('(') 
     1634            sep = '' 
     1635            for p in .params 
     1636                s.append(sep) 
     1637                sep = ', ' 
     1638                s.append(p.name) 
     1639                s.append(' as ') 
     1640                s.append(p.type.name) 
     1641            s.append(')') 
     1642        if .returnType <> .compiler.voidType 
     1643            s.append(' as ') 
     1644            s.append(.returnType.name) 
     1645        return s.toString 
    15591646         
    15601647class GenericParam inherits CobraType is partial 
    15611648    """ 
  • Source/BinaryOpExpr.cobra

     
    373373                _type = leftType 
    374374            else if cannotMix 
    375375                .throwError('Cannot mix types [_left.type.name] and [_right.type.name] for arithmetic.') 
     376            else if _left.isKindOf(.compiler.delegateType) 
     377                _type = tpassthrough # Not really but allows catching += -= below 
     378     
    376379            if _type is nil 
    377380                sugg = 'Try finding a method that performs this function.' 
    378381                if leftType == rightType 
     
    404407        base._bindImp 
    405408        # TODO: does NumericPromoExpr cover everything we need? 
    406409        # C# and other languages use += and -= on delegates and events, but Cobra does not. 
    407         if .left.type inherits MethodSig 
    408             # TODO: error 
    409             pass 
    410         else if .left.type.nonNil.isDescendantOf(.compiler.delegateType) 
     410        if .left.type inherits MethodSig or .left.type.nonNil.isDescendantOf(.compiler.delegateType) 
    411411            leftSource = .left.toCobraSource 
    412412            rightSource = .right.toCobraSource 
    413413            if not .right inherits RefExpr, rightSource = 'ref ' + rightSource 
  • Source/Container.cobra

     
    2525        May return nil if no such member exists. 
    2626        Case-sensitive. 
    2727        """ 
     28         
     29    def sigForMethodSig(msig as MethodSig) as MethodSig? 
     30        """ 
     31        Returns the first method signature of this container matching the provided signature, including  
     32        any inherited methodSignatures ( i.e follows inheritance chain). 
     33        A 'matching' signature has the same returnType, paramList size and paramList types in the same order. 
     34        May return nil if no such sig exists. 
     35        """ 
    2836# TODO: 
    2937#       require 
    3038#           # TODO: not .compiler.isParsing 
     
    8391    var _declsInOrder as List<of TMember> 
    8492    var _declsByName as Dictionary<of String, TMember> 
    8593    var _declsByNameCI as Dictionary<of String, TMember> 
     94    var _sigsInOrder as List<of MethodSig> 
    8695    var _docString as String 
    8796    var _isNames as IList<of String> 
    8897 
     
    93102        base.init(token, name) 
    94103        _initParent(parent) 
    95104        _declsInOrder = List<of TMember>() 
     105        _sigsInOrder = List<of MethodSig>() 
    96106        _declsByName = Dictionary<of String, TMember>() 
    97107        _declsByNameCI = Dictionary<of String, TMember>() 
    98108        _isNames = isNames.toList 
     
    161171            else 
    162172                _declsByNameCI.add(decl.name.toLower, decl) 
    163173 
     174    def addSig(signat as MethodSig)          
     175        _sigsInOrder.add(signat) 
     176 
    164177    def declForName(name as String) as TMember? 
    165178        require 
    166179            name.length 
     
    345358 
    346359    def cloneCollections 
    347360        _declsInOrder = List<of TMember>(_declsInOrder) 
     361        _sigsInOrder  = List<of MethodSig>(_sigsInOrder) 
    348362        _declsByName = Dictionary<of String, TMember>(_declsByName) 
    349363        _declsByNameCI = Dictionary<of String, TMember>(_declsByNameCI) 
    350  
    351  
     364         
     365    def sigForMethodSig(ms as MethodSig) as MethodSig? 
     366        """ 
     367        Search inheritance tree for a MethodSig matching the given parameter.  
     368        Look in this containers siglist for a matching sig, If none recursively look in parent. 
     369        Return first matching sig or nil if none found 
     370        """ 
     371        aSig = _haveSigForMethodSig(ms) 
     372        if aSig 
     373            return aSig 
     374             
     375        if .parent 
     376            return .parent.sigForMethodSig(ms) 
     377        return nil 
     378         
     379    def _haveSigForMethodSig(ms as MethodSig) as MethodSig? 
     380        """Return first matching sig in this container matching the MethodSig parameter or nil if none.""" 
     381        for aSig in _sigsInOrder 
     382            #print ms.name, aSig.name 
     383            if aSig.isAnonymousMatch(ms) 
     384                return aSig 
     385        return nil 
     386             
    352387interface IMember 
    353388    is partial 
    354389    inherits INamedNode 
  • Source/NameSpace.cobra

     
    264264        for ud in _useDirectives 
    265265            m = ud.extensionMemberFor(box, name) 
    266266            if m, return m 
    267         return if(_superNameSpace, _superNameSpace._extensionMemberFromUseDirectives(box, name), nil) 
     267        if _superNameSpace 
     268            m = _superNameSpace._extensionMemberFromUseDirectives(box, name) 
     269            if m, return m 
     270        return nil 
     271         
     272    def sigForMethodSig(ms as MethodSig) as MethodSig? is override 
     273        """ 
     274        Search namespace and UseDirectives for a MethodSig matching the given parameter.  
     275        Return first matching sig or nil if none found. 
     276        """ 
     277        if not .isUnified 
     278            m = _unifiedNameSpace.sigForMethodSig(ms) 
     279            if m  
     280                #print 'MATCH (u-ns [.name])', m.name 
     281                return m 
     282            return _sigMethodFromUseDirectives(ms) 
     283        else 
     284            asig = _haveSigForMethodSig(ms)  # from Container baseclass 
     285            if asig 
     286                #print 'MATCH (ns)', asig.name 
     287                return asig 
     288            if _superNameSpace 
     289                s = _superNameSpace._sigMethodFromUseDirectives(ms) 
     290                if s  
     291                    #print 'MATCH (super-ns)', s.name 
     292                    return s 
     293        #print 'NO-MATCH (ns [.name])', ms.name 
     294        return nil 
    268295 
     296 
     297    def _sigMethodFromUseDirectives(ms as MethodSig) as MethodSig? 
     298        """ Look for MethodSig in namespaces referenced by the useDirectives""" 
     299        for ud in _useDirectives 
     300            #print 'USEDIR', ud.fullName 
     301            s = ud.sigMethodFor(ms) 
     302            if s  
     303                #print 'MATCH (usedir [ud.fullName])', s.name 
     304                return s 
     305        if _superNameSpace 
     306            s = _superNameSpace._sigMethodFromUseDirectives(ms) 
     307            if s 
     308                #print 'MATCH (ud super-ns)', s.name 
     309                return s 
     310        #print 'NO-MATCH (usedirs)', ms.name 
     311        return nil 
     312             
     313 
    269314    def symbolForName(name as String) as IMember? 
    270315        if not .isUnified 
    271316            x = _unifiedNameSpace.symbolForName(name) 
     
    276321            if members.count == 1 
    277322                return List<of IMember>(members)[0]  # TODO: feels silly. maybe Set should have a .only method with require .count==1 
    278323            else if members.count > 1 
    279                 membersList = List<of IMember>(members) 
    280                 membersList.sort(do(a as IMember, b as IMember)) 
    281                     return a.parentNameSpace.fullName.compareTo(b.parentNameSpace.fullName) 
    282                 spaces = (for m in membersList get '"[m.parentNameSpace.fullName]"').join(', ', ' and ') 
    283                 if .compiler and .compiler.nodeStack.peek inherits ISyntaxNode 
    284                     node = .compiler.nodeStack.peek 
    285                 else 
    286                     node = this 
    287                 node.throwError('Ambiguous reference "[name]" found in namespaces [spaces].') 
     324                _throwAmbiguousRefError(name, members) 
    288325        else 
    289326            # our decl? 
    290327            # TODO: should this come before checking our name? what does C# do? 
     
    298335                if x, return x 
    299336#/ 
    300337        return nil 
    301  
     338         
     339    def _throwAmbiguousRefError(name as String, members as Set<of IMember>) 
     340        membersList = List<of IMember>(members) 
     341        membersList.sort(do(a as IMember, b as IMember)) 
     342            return a.parentNameSpace.fullName.compareTo(b.parentNameSpace.fullName) 
     343        spaces = (for m in membersList get '"[m.parentNameSpace.fullName]"').join(', ', ' and ') 
     344        if .compiler and .compiler.nodeStack.peek inherits ISyntaxNode 
     345            node = .compiler.nodeStack.peek 
     346        else 
     347            node = this 
     348        node.throwError('Ambiguous reference "[name]" found in namespaces [spaces].') 
     349         
    302350    def _symbolsForNameFromUseDirectives(name as String, members as Set<of IMember>) 
    303351        """ 
    304352        Populates `members` with all symbols from `use` directives that match `name`. 
     
    308356            if x, members.add(x) 
    309357        if _superNameSpace 
    310358            _superNameSpace._symbolsForNameFromUseDirectives(name, members) 
    311  
     359             
    312360    def addDecl(decl as INameSpaceMember) is override 
    313361        base.addDecl(decl) 
    314362        if decl inherits NameSpace 
     
    332380                pass 
    333381            else 
    334382                _unifiedNameSpace.addDecl(decl) 
     383        if decl inherits MethodSig 
     384            base.addSig(decl) 
    335385 
    336386    def addUseDirective(ud as UseDirective) 
    337387        _useDirectives.add(ud) 
     
    403453        .addField('boundNameSpace', _boundNameSpace) 
    404454 
    405455    get boundNameSpace from var 
     456    get fullName from var 
    406457 
    407458    def extensionMemberFor(box as Box, name as String) as IMember? 
    408459        require .didBindUse 
     
    411462    def findSymbol(name as String) as IMember? 
    412463        require .didBindUse 
    413464        return _boundNameSpace.symbolForName(name) 
     465 
     466    def sigMethodFor(ms as MethodSig) as MethodSig?  
     467        require .didBindUse 
     468        return _boundNameSpace.sigForMethodSig(ms) 
  • Tests/120-classes/320-construct-prop-set.cobra

     
     1sig DoSomethingSig 
     2# Signature hoisted for ref inference Jun-2010.  
     3#Needs to be accessible to both class X and class Stuff  
     4# (or add a Sig to class X compatible with one in class Stuff) 
     5 
    16class X 
    27 
    38    shared 
     
    6772    pro style from var 
    6873 
    6974 
    70     sig DoSomethingSig 
     75    # this sig needs to be accessible to both Stuff and X 
     76    #sig DoSomethingSig 
    7177 
    7278    pro doSomething from var as DoSomethingSig? 
    7379 
  • Tests/220-delegates-etc/100-delegates/112-declare-sig-inside-class.cobra

     
    3232 
    3333class Program 
    3434 
     35    # need this additional sig type now ref type inference is implemented  
     36    # and searching for compat sig  only up inheritance tree and  
     37    # 'use'ed namespaces. 
     38    # Test is now that the sig types in each class are assignment compatible 
     39    sig BinaryOpP(a as int, b as int) as int 
     40 
    3541    def main is shared 
    3642        Program().run 
    3743     
  • Tests/220-delegates-etc/100-delegates/172-infer-ref-type-no-sig.cobra

     
     1# Ref type inference and methodSig auto generation and injection 
     2class MyType 
     3    pass 
     4 
     5class AutoGenMethodSig 
     6    #sig MethNoArg 
     7 
     8    # non simple signature that doesnt collide with any generic System delegates 
     9    # e.g System.Action (one arg, no return),  
     10    #     System.EventHandler(2 args, no return), 
     11    #     System.Comparison(2 args, int return) 
     12    def methUnknown(r as MyType, r1 as MyType) as MyType 
     13        return r 
     14     
     15    def methUnknown2(r as MyType, r1 as MyType) as MyType 
     16        return r1 
     17     
     18    def methAction0 
     19        pass 
     20         
     21    def methAction(r as MyType) 
     22        pass 
     23         
     24    def main is shared 
     25        c = AutoGenMethodSig() 
     26             
     27        meUnk = ref c.methUnknown # .warning. No signature matching 
     28        assert meUnk.typeOf == SigFor_methUnknown # autogen Sig and inserted 
     29     
     30        meUnk2 = ref c.methUnknown2 
     31        assert meUnk2.typeOf == SigFor_methUnknown # found autogen Sig 
     32         
     33        # was matchiung to CrossAppDomainDelegate 
     34        meAct0 = ref c.methAction0   # .warning. No signature matching 
     35        assert meAct0.typeOf == SigFor_methAction0 
     36        #assert meAct0.typeOf == MethNoArg 
     37         
     38        # was matching to Converter<to,> 
     39        meAct1 = ref c.methAction # .warning. No signature matching 
     40        print meAct1 
     41         
  • Tests/220-delegates-etc/100-delegates/170-infer-ref-type.cobra

     
     1# Test Ref type inference and matching autogenerated ref sig 
     2# to App or system MethodSigs 
     3 
     4sig SigForMethOuter(s as String) 
     5 
     6class RefType 
     7     
     8    sig SigForMethInner(a as int) 
     9    sig SigForDynamic(a as dynamic?) as bool 
     10     
     11    def meth(a as int) 
     12        print a 
     13     
     14    def methOuter(s as String) 
     15        print s 
     16         
     17    def methUnknown(r) 
     18        pass 
     19     
     20    def methConcDy(a as Object?) as bool 
     21        return false 
     22     
     23    # EventHandler  
     24    def handleEvent( src as Object, args as EventArgs) 
     25        pass 
     26         
     27    # ResolveEventHandler  
     28    def handleResolveEvent(sender as Object, args as ResolveEventArgs) as System.Reflection.Assembly? 
     29        return System.Reflection.Assembly.getExecutingAssembly 
     30 
     31    def chkMySig 
     32        me = ref .meth 
     33        assert  me.typeOf == SigForMethInner 
     34         
     35    def main is shared 
     36        c = RefType() 
     37        c.chkMySig 
     38         
     39        me = ref c.meth  # auto type me 
     40        assert me.typeOf == SigForMethInner 
     41     
     42        me1 = ref c.methOuter 
     43        assert me1.typeOf == SigForMethOuter 
     44         
     45         
     46        # equivalence Object? and dynamic arg 
     47        mdy = ref c.methConcDy 
     48        assert mdy.typeOf == SigForDynamic 
     49     
     50        # match to System MethodSigs (from use assembly/dll) 
     51        meh = ref c.handleEvent 
     52        assert meh.typeOf == System.EventHandler 
     53     
     54        meres  = ref c.handleResolveEvent 
     55        assert meres.typeOf == System.ResolveEventHandler 
     56 
     57        # ticket 140 
     58        for x in [ref c.meth, ref c.meth] 
     59            assert x.typeOf == SigForMethInner 
     60     
     61        for y in [ref c.methOuter, ref c.methOuter] 
     62            assert y.typeOf == SigForMethOuter 
     63             
     64        #meUnk = ref c.methUnknown 
     65        #print 'me2', meUnk 
     66 
     67             
  • Tests/220-delegates-etc/100-delegates/100-basics.cobra

     
     1sig SigCompareInt(a as int, b as int) as int  
     2# Above Add for ref inference  Jun-2010. Not find/match generic delegate 
     3 
    14class X 
    25 
    36    def main is shared 
  • Developer/IntermediateReleaseNotes.text

     
    6060 
    6161* Enumeration members can now be placed on the same line separated by commas. 
    6262 
     63* Provide type inference on ref expressions (find matching Sigs for ref to method) : tickets:39,40,138 
    6364 
    6465================================================================================ 
    6566Library