Wiki

Ticket #178: inner-classes.patch

File inner-classes.patch, 10.5 KB (added by hopscc, 8 years ago)
  • Source/BackEndClr/SharpGenerator.cobra

     
    10321032            return 
    10331033        if .isGenericDef  # sorry, but static methods always require a type arg even if you don't need it. workaround. make another class with a 'test' section that tests the generic class TODO: make Cobra do this, but then watch for use of the generic param! 
    10341034            return 
    1035         assert .parentNameSpace 
     1035        #assert .parentNameSpace # suppress for nested classes  
    10361036        sw.write('\t\t[.sharpRef].RunTestsIfNeeded();\n') 
    10371037        _didWriteSharpTestInvocation = true 
    10381038 
     
    10431043class Class 
    10441044    is partial 
    10451045 
     1046    get sharpRef as String is override 
     1047        # for getting fully dotted name for nested classes 
     1048        sb = StringBuilder() 
     1049        if .enclosure 
     1050            sb.append(.enclosure.sharpRef + '.') 
     1051        sb.append(base.sharpRef) 
     1052        return sb.toString 
     1053 
    10461054    get sharpInit as String is override 
    10471055        return 'null' 
    10481056 
     
    11281136class Struct 
    11291137    is partial 
    11301138 
     1139    get sharpRef as String is override 
     1140        # for getting fully dotted name for nested classes 
     1141        sb = StringBuilder() 
     1142        if .enclosure 
     1143            sb.append(.enclosure.sharpRef + '.') 
     1144        sb.append(base.sharpRef) 
     1145        return sb.toString 
     1146 
    11311147    get sharpInit as String is override 
    11321148        return ''  # blank to indicate there is no valid init 
    11331149 
     
    35613577    is partial 
    35623578 
    35633579    def writeSharpDef(sw as CurlyWriter, parens as bool) is override 
    3564         sharpRef = _containedType.sharpRef 
     3580        sharpRef =  _containedType.sharpRef 
    35653581        # handle the case of "X.X" where namespace and class are both called "X". 
    35663582        # C# chokes on it because the first "X" is considered to be the type 
    35673583        if .curBox.name + '.' in sharpRef 
    35683584            sharpRef = 'global::' + sharpRef 
    35693585        if _requiresTypeOf() 
    35703586            sw.write('typeof(') 
    3571             sw.write(_containedType.sharpRef) 
     3587            sw.write(sharpRef) 
    35723588            sw.write(')') 
    35733589        else 
    3574             sw.write(_containedType.sharpRef) 
     3590            sw.write(sharpRef) 
    35753591 
    35763592    def _requiresTypeOf as bool 
    35773593        # Cobra never requires that you wrap a type reference in typeof(Foo). 
  • Source/Boxes.cobra

     
    10721072    """ 
    10731073     
    10741074    var _addsProxies as List<of ITypeProxy> 
     1075    var _enclosure as ClassOrStruct? 
     1076 
     1077    pro enclosure from var  # enclosure for nested class/struct 
    10751078     
    10761079    cue init(token as IToken, idToken as IToken, name as String, paramList as List<of IType>, isNames as List<of String>, attribs as AttributeList, implementsNodes as List<of ITypeProxy>, addsProxies as List<of ITypeProxy>, docString as String?) 
    10771080        base.init(token, idToken, name, paramList, isNames, attribs, implementsNodes, docString) 
    10781081        _addsProxies = addsProxies 
    10791082 
     1083    def addRefFields 
     1084        base.addRefFields 
     1085        .addField('enclosure', _enclosure) 
     1086 
    10801087    def _bindInh 
    10811088        # mixins act as interfaces (and more) 
    10821089        for proxy in _addsProxies 
  • Source/CobraParser.cobra

     
    665665         
    666666        theClass = Class(wordToken, idToken, name, .makeList<of IType>(genericParams), typeSpecs.isNames, typeSpecs.attributes, inheritsProxy, typeSpecs.implementsProxies, typeSpecs.addsProxies, docString) 
    667667 
    668         # TODO when supporting nested classes, look at the _boxStack and set a back pointer here 
     668        # For nested classes, set pointer to enclosure 
     669        if _boxStack.count 
     670            encl = .curBox  
     671            if encl inherits ClassOrStruct 
     672                theClass.enclosure = encl 
     673 
    669674        _boxStack.push(theClass) 
    670675#       .isNamesStack = Stack<of String> 
    671676        .bodiedBoxMemberDecls(theClass) 
     
    928933 
    929934        theStruct = Struct(wordToken, idToken, name, .makeList<of IType>(genericParams), typeSpecs.isNames, typeSpecs.attributes, nil, typeSpecs.implementsProxies, typeSpecs.addsProxies, docString) 
    930935 
    931         # TODO when supporting nested classes, look at the boxStack and set a back pointer here 
     936        # For nested classes, set pointer to enclosure 
     937        if _boxStack.count 
     938            encl = .curBox  
     939            if encl inherits ClassOrStruct 
     940                theStruct.enclosure = encl 
     941 
    932942        _boxStack.push(theStruct) 
    933943#       .isNamesStack = Stack(str) 
    934944        .bodiedBoxMemberDecls(theStruct) 
     
    11741184                    on 'SIG', .addDecl(box, .declareMethodSig) 
    11751185                    on 'SHARED', .bodiedBoxMemberDeclsShared(box) 
    11761186                    on 'TEST', .testSection(box) 
     1187                    on 'CLASS',  .addDecl(box, .classDecl)  # nested classes 
     1188                    on 'STRUCT', .addDecl(box, .structDecl) # nested classes 
    11771189                    else 
    11781190                        branch .peek.text 
    11791191                            on 'ensure', sugg = 'invariant' 
     
    11811193                            else, sugg = '' 
    11821194                        if sugg <> '' 
    11831195                            sugg = ' Instead of "[.peek.text]", try "[sugg]".' 
    1184                         .throwError('Got [.peek] when expecting def, enum, get, invariant, pro, set, shared, sig, test, or var.[sugg]') 
     1196                        .throwError('Got [.peek] when expecting def, enum, get, invariant, pro, set, shared, sig, test, class or var.[sugg]') 
    11851197            .dedent 
    11861198 
    11871199    def addDecl(box as Box, member as IBoxMember?) 
  • Tests/120-classes/330-nested.cobra

     
     1# simple nested class - access from inside 
     2class Enclosing 
     3     
     4    class Nested 
     5        cue init 
     6            base.init 
     7 
     8        def geti as int 
     9            return 1 
     10             
     11    def geti as int 
     12        return 99 
     13         
     14    def main 
     15        a = Enclosing() 
     16        assert a.geti == 99 
     17        n=Enclosing.Nested() 
     18        assert n.geti == 1 
     19         
  • Tests/120-classes/332-nested-multi.cobra

     
     1# multiple levels of Nested class, infereed and explicit typing 
     2class Enclosing 
     3     
     4    class Nested is public 
     5 
     6        def geti as int 
     7            return 1 
     8 
     9        class Nested2 
     10 
     11            def geti as int 
     12                return 2 
     13 
     14    class NestedOther 
     15 
     16        get geti 
     17            return 10 
     18             
     19    def geti as int  
     20        return 99 
     21     
     22class Enc 
     23    def main 
     24        a = Enclosing() 
     25        assert a.geti == 99 
     26 
     27        en=Enclosing.Nested() 
     28        assert en.geti == 1 
     29     
     30        enn=Enclosing.Nested.Nested2() 
     31        assert enn.geti == 2 
     32         
     33        eno as Enclosing.NestedOther? 
     34        eno = Enclosing.NestedOther() 
     35        assert eno.geti == 10 
     36         
  • Tests/120-classes/334-nested-idiom.cobra

     
     1# Test of C# idiom for Java-like implicit enclosure ref for nested classes. 
     2# as per  http://blogs.msdn.com/oldnewthing/archive/2006/08/01/685248.aspx 
     3 
     4class Enclosing 
     5    var s as String = 'no-thing' 
     6     
     7    class Nested  
     8        var _parent  
     9 
     10        cue init(parent) # Java does this implicitly 
     11            base.init 
     12            _parent = parent 
     13         
     14        def getS as String 
     15            return _parent.s 
     16             
     17     
     18    def mkNested as Nested 
     19        return Enclosing.Nested(this) 
     20             
     21    def main 
     22        e = Enclosing() 
     23        #n = Enclosing.Nested()  # no no-arg ctor 
     24        n = Enclosing.Nested(e)  
     25        n1 = e.Nested(e) 
     26        assert n.getS == 'no-thing' 
     27        assert n1.getS == 'no-thing' 
     28         
     29        n2 = e.mkNested 
     30        assert n2.getS == 'no-thing' 
     31        delta = 'activated' 
     32        e.s = delta 
     33        assert n.getS  == delta 
     34        assert n1.getS == delta 
     35        assert n2.getS == delta 
     36        assert n <> n1 
     37        assert n <> n2 
     38        assert n1 <> n2 
  • Tests/140-structs/402-nested-multi.cobra

     
     1# nested struct in struct and classes accessed from a third class 
     2struct Enclosing 
     3     
     4    struct Nested 
     5        def geti as int 
     6            return 1 
     7 
     8        struct Nested2 
     9            def geti as int 
     10                return 2 
     11 
     12    struct NestedOther 
     13        def geti as int 
     14            return 10 
     15             
     16    def geti as int  
     17        return 99 
     18     
     19class EnclosingClass 
     20     
     21    struct Nested is public 
     22 
     23        def geti as int 
     24            return 101 
     25 
     26        struct Nested2 
     27            def geti as int 
     28                return 102 
     29 
     30    struct NestedOther 
     31        def geti as int 
     32            return 110 
     33             
     34    def geti as int  
     35        return 199 
     36         
     37class EntryPt 
     38    def main 
     39        s = Enclosing() 
     40        assert s.geti == 99 
     41 
     42        sen=Enclosing.Nested() 
     43        assert sen.geti == 1 
     44         
     45        senn1 as Enclosing.Nested.Nested2 = Enclosing.Nested.Nested2() 
     46        assert senn1.geti == 2 
     47     
     48        senn =Enclosing.Nested.Nested2() 
     49        assert senn.geti == 2 
     50         
     51        seno = Enclosing.NestedOther() 
     52        assert seno.geti == 10 
     53     
     54        c = EnclosingClass() 
     55        assert c.geti == 199 
     56 
     57        cen=EnclosingClass.Nested() 
     58        assert cen.geti == 101 
     59     
     60        cenn=EnclosingClass.Nested.Nested2() 
     61        assert cenn.geti == 102 
     62         
     63        ceno = EnclosingClass.NestedOther() 
     64        assert ceno.geti == 110 
     65         
  • Tests/140-structs/400-nested.cobra

     
     1# nested struct in class or struct 
     2 
     3struct EnclStruct 
     4    class Nested 
     5        def geti as int 
     6            return 1 
     7             
     8    struct SNested 
     9        def geti as int 
     10            return 10 
     11 
     12    def geti as int 
     13        return 99 
     14 
     15 
     16class Enclosing 
     17     
     18    struct NestedStruct 
     19        def geti as int 
     20            return 1 
     21 
     22    def geti as int 
     23        return 99 
     24         
     25    def main 
     26     
     27        # class with nested struct 
     28        e = Enclosing() 
     29        assert e.geti == 99 
     30        ens=Enclosing.NestedStruct() 
     31        assert ens.geti == 1 
     32         
     33        # Struct with nested class 
     34        es = EnclStruct() 
     35        assert es.geti == 99 
     36        esn=EnclStruct.Nested() 
     37        assert esn.geti == 1 
     38         
     39        ess=EnclStruct.SNested() 
     40        assert ess.geti == 10 
  • Developer/IntermediateReleaseNotes.text

     
    4848 
    4949* Sets with duplicate members such as `{1, 0, 1}` now generate a warning. 
    5050 
     51* Provide support for inner/nested classes (structs and classes) within classes and structs 
     52 
    5153================================================================================ 
    5254Library 
    5355================================================================================