Changeset 1711

Show
Ignore:
Timestamp:
10/28/08 00:02:03 (2 months ago)
Author:
Chuck.Esterbrook
Message:

Implement generic constraints on methods.

Location:
cobra/trunk
Files:
1 added
4 modified

Legend:

Unmodified
Added
Removed
  • cobra/trunk/Source/CobraParser.cobra

    r1704 r1711  
    664664                        .throwError('Class names must start with an uppercase letter in order to avoid collisions with other identifiers such as arguments and local variables.') 
    665665 
    666                 params = .declGenericParams(token) 
    667                 name = .nameForDeclGenericParams(token, params) 
     666                genericParams = .declGenericParams(token) 
     667                name = .nameForDeclGenericParams(token, genericParams) 
    668668 
    669669                .indent 
     
    672672                attribs = .hasAttribs 
    673673 
    674                 .genericConstraints(token, params) 
     674                .genericConstraints(token, genericParams) 
    675675 
    676676                baseNode as ITypeProxy? 
     
    688688                                        .grab 
    689689                                        break 
    690                                 if expectComma 
    691                                         .expect('COMMA') 
     690                                if expectComma, .expect('COMMA') 
    692691                                interfaceName = .typeId  # using .typeId since interface could be qualified (Foo.Bar) or a generic like IEnumerable<of T> 
    693692                                interfaceNames.add(interfaceName) 
     
    696695                docString = .docString 
    697696 
    698                 theClass = Class(token, name, .makeList(List<of IType>(), params) to List<of IType>, isNames, attribs, baseNode, interfaceNames, docString) 
     697                theClass = Class(token, name, .makeList<of IType>(genericParams), isNames, attribs, baseNode, interfaceNames, docString) 
    699698 
    700699                # TODO when supporting nested classes, look at the _boxStack and set a back pointer here 
     
    706705                return theClass 
    707706 
    708         def makeList(t as System.Collections.IList, u as System.Collections.IList) as System.Collections.IList 
     707        def makeList<of TOut>(inList as System.Collections.IList) as List<of TOut> 
    709708                # This feels awkward as hell, but it's a .NET typing thing, not a Cobra thing. 
    710709                # I need List<of GenericParam> in the my local code for declaring generics, but the various box inits need to accept List<of IType> 
     
    712711                # List<of IType>(params promote to IEnumerable<of IType>) 
    713712                # "promote to" works for generics where the new promo type has parameter types that are the same or ancestors to the original parameter types *and* ... ??? 
    714                 for item in u 
    715                         t.add(item) 
    716                 return t 
     713                outList = List<of TOut>() 
     714                for item in inList 
     715                        outList.add(item to TOut) 
     716                return outList 
    717717 
    718718        def hasAttribs as AttributeList 
     
    857857                docString = .docString 
    858858 
    859                 theInterface = Interface(token, name, .makeList(List<of IType>(), params) to List<of IType>, isNames, attribs, baseNames, docString) 
     859                theInterface = Interface(token, name, .makeList<of IType>(params), isNames, attribs, baseNames, docString) 
    860860 
    861861                _boxStack.push(theInterface) 
     
    908908                docString = .docString 
    909909 
    910                 theStruct = Struct(token, name, .makeList(List<of IType>(), params) to List<of IType>, isNames, attribs, baseName, interfaceNames, docString) 
     910                theStruct = Struct(token, name, .makeList<of IType>(params), isNames, attribs, baseName, interfaceNames, docString) 
    911911 
    912912                # TODO when supporting nested classes, look at the boxStack and set a back pointer here 
     
    10091009        def genericConstraints(token as IToken, params as List<of GenericParam>) 
    10101010                while .optional('WHERE') 
    1011                         if token.which<>'OPEN_GENERIC' 
    1012                                 .throwError('Unexpected where clause for non-generic class.') 
     1011                        if token.which <> 'OPEN_GENERIC' 
     1012                                .throwError('Unexpected where clause for non-generic declaration.') 
    10131013                        paramName = .expect('ID').value 
     1014                        # CC: found = find param in params where param.name == paramName 
    10141015                        found = false 
    10151016                        for param in params 
    1016                                 if param.name==paramName 
     1017                                if param.name == paramName 
    10171018                                        found = true 
    10181019                                        break 
    1019                         if not found 
    1020                                 .throwError('Unknown generic parameter "[paramName]".') 
    1021                         if param.constraints.count 
    1022                                 .throwError('Already specified constraints for "[paramName]".') 
     1020                        if not found, .throwError('Unknown generic parameter "[paramName]".') 
     1021                        if param.constraints.count, .throwError('Already specified constraints for "[paramName]".') 
    10231022                        .expect('MUST') 
    10241023                        .expect('BE') 
    10251024                        expectComma = false 
    10261025                        while true 
    1027                                 if expectComma 
    1028                                         .expect('COMMA') 
     1026                                if expectComma, .expect('COMMA') 
    10291027                                param.constraints.add(.genericConstraint) 
    1030                                 if .optional('EOL') 
    1031                                         break 
     1028                                if .optional('EOL'), break 
    10321029                                expectComma = true 
    10331030 
     
    12591256                        .throwError('Encountered [opener.which] when expecting an identifier.') 
    12601257                if opener.which == 'OPEN_GENERIC' 
    1261                         genericParams = .makeList(List<of IType>(), .declGenericParams(opener)) to List<of IType> 
    1262                 else 
    1263                         genericParams = List<of IType>() 
     1258                        genericParams = .declGenericParams(opener) 
     1259                else 
     1260                        genericParams = List<of GenericParam>() 
    12641261                name = opener.value to String 
    12651262                curBox = .curBox 
     
    13091306                        # No additional specs like attributes, contracts or body 
    13101307                        nothingMore = true 
    1311                         if not hasIsNames 
    1312                                 isNames = List<of String>(_isNamesStack) 
     1308                        if not hasIsNames, isNames = List<of String>(_isNamesStack) 
    13131309                        attribs = AttributeList() 
    13141310                        implementsType = nil to ITypeProxy? 
     
    13171313                        # parse additional method declaration 
    13181314                        nothingMore = false 
    1319                         if not hasIsNames 
    1320                                 isNames = .isDeclNames 
     1315                        if not hasIsNames, isNames = .isDeclNames 
     1316                        .genericConstraints(opener, genericParams) 
    13211317                        attribs = .hasAttribs 
    13221318                        implementsType = if(.optional('IMPLEMENTS'), .typeId, nil) 
     
    13331329                        method = Initializer(token, .curBox, params, isNames, attribs, docString) 
    13341330                else 
    1335                         method = Method(token, .curBox, name, genericParams, params, returnType, implementsType, isNames, attribs, docString) 
     1331                        method = Method(token, .curBox, name, .makeList<of IType>(genericParams), params, returnType, implementsType, isNames, attribs, docString) 
    13361332                if nothingMore 
    13371333                        if not 'abstract' in isNames and not curBox inherits Interface 
  • cobra/trunk/Source/Members.cobra

    r1662 r1711  
    665665        def _bindInt is override 
    666666                base._bindInt 
     667                # TODO: cleanup. try pushing this to .bindInt 
    667668                .compiler.codeMemberStack.push(this) 
    668669                try 
     
    10131014 
    10141015        def _bindInt is override 
    1015                 for param in _genericParams 
    1016                         param.bindInt 
    1017                 base._bindInt 
    1018                 if .name == '__init__' 
    1019                         .compiler.warning(this, 'Initializers are named "init" with no surrounding underscores.') 
     1016                .compiler.codeMemberStack.push(this) 
     1017                try 
     1018                        assert .compiler.codeMemberStack.peek is this 
     1019                        for param in _genericParams 
     1020                                param.bindInt 
     1021                        base._bindInt 
     1022                        if .name == '__init__' 
     1023                                .compiler.warning(this, 'Initializers are named "init" with no surrounding underscores.') 
     1024                finally 
     1025                        .compiler.codeMemberStack.pop 
    10201026 
    10211027        def _bindImp is override 
  • cobra/trunk/Source/Node.cobra

    r1708 r1711  
    419419                                _didStartBindInh = true 
    420420                                _isBindingInh = true 
    421                                 if .compiler 
    422                                         .compiler.nodeStack.push(this) 
     421                                if .compiler, .compiler.nodeStack.push(this) 
    423422                                try 
    424423                                        _didBindInhBase = false 
     
    428427                                finally 
    429428                                        _finishChildReplacements 
    430                                         if .compiler 
    431                                                 .compiler.nodeStack.pop 
     429                                        if .compiler, .compiler.nodeStack.pop 
    432430                                        _isBindingInh = false 
    433431 
  • cobra/trunk/Source/SharpGenerator.cobra

    r1702 r1711  
    17511751                sw.write('[returnType.sharpRef] [name][.sharpGenericParams]') 
    17521752                .writeSharpParams(sw) 
     1753                if .genericParams.count 
     1754                        sw.indent 
     1755                        for param in .genericParams 
     1756                                if param inherits GenericParam 
     1757                                        param.writeSharpConstraint(sw) 
     1758                        sw.dedent 
    17531759                if .isInterfaceMember and not .isExtensionMember 
    17541760                        sw.write(';\n') 
    17551761                else 
    1756                         if .isAbstract 
    1757                                 sw.writeLine(';') 
    1758                         else 
    1759                                 .writeSharpImp(sw, false) 
    1760                         if _requirePart 
    1761                                 _requirePart.writeSharpMethod(sw) 
    1762                         if _ensurePart 
    1763                                 _ensurePart.writeSharpMethod(sw) 
    1764                         if .compiler.includeTests 
    1765                                 .writeSharpTest(sw) 
     1762                        if .isAbstract, sw.writeLine(';') 
     1763                        else, .writeSharpImp(sw, false) 
     1764                        if _requirePart, _requirePart.writeSharpMethod(sw) 
     1765                        if _ensurePart, _ensurePart.writeSharpMethod(sw) 
     1766                        if .compiler.includeTests, .writeSharpTest(sw) 
    17661767 
    17671768        def writeSharpImpHeader(sw as SharpWriter)