Changeset 1711
- Timestamp:
- 10/28/08 00:02:03 (2 months ago)
- Location:
- cobra/trunk
- Files:
-
- 1 added
- 4 modified
-
Source/CobraParser.cobra (modified) (13 diffs)
-
Source/Members.cobra (modified) (2 diffs)
-
Source/Node.cobra (modified) (2 diffs)
-
Source/SharpGenerator.cobra (modified) (1 diff)
-
Tests/240-generics/400-generic-methods/130-generic-method-constraints.cobra (added)
Legend:
- Unmodified
- Added
- Removed
-
cobra/trunk/Source/CobraParser.cobra
r1704 r1711 664 664 .throwError('Class names must start with an uppercase letter in order to avoid collisions with other identifiers such as arguments and local variables.') 665 665 666 params = .declGenericParams(token)667 name = .nameForDeclGenericParams(token, params)666 genericParams = .declGenericParams(token) 667 name = .nameForDeclGenericParams(token, genericParams) 668 668 669 669 .indent … … 672 672 attribs = .hasAttribs 673 673 674 .genericConstraints(token, params)674 .genericConstraints(token, genericParams) 675 675 676 676 baseNode as ITypeProxy? … … 688 688 .grab 689 689 break 690 if expectComma 691 .expect('COMMA') 690 if expectComma, .expect('COMMA') 692 691 interfaceName = .typeId # using .typeId since interface could be qualified (Foo.Bar) or a generic like IEnumerable<of T> 693 692 interfaceNames.add(interfaceName) … … 696 695 docString = .docString 697 696 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) 699 698 700 699 # TODO when supporting nested classes, look at the _boxStack and set a back pointer here … … 706 705 return theClass 707 706 708 def makeList (t as System.Collections.IList, u as System.Collections.IList) as System.Collections.IList707 def makeList<of TOut>(inList as System.Collections.IList) as List<of TOut> 709 708 # This feels awkward as hell, but it's a .NET typing thing, not a Cobra thing. 710 709 # I need List<of GenericParam> in the my local code for declaring generics, but the various box inits need to accept List<of IType> … … 712 711 # List<of IType>(params promote to IEnumerable<of IType>) 713 712 # "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 717 717 718 718 def hasAttribs as AttributeList … … 857 857 docString = .docString 858 858 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) 860 860 861 861 _boxStack.push(theInterface) … … 908 908 docString = .docString 909 909 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) 911 911 912 912 # TODO when supporting nested classes, look at the boxStack and set a back pointer here … … 1009 1009 def genericConstraints(token as IToken, params as List<of GenericParam>) 1010 1010 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.') 1013 1013 paramName = .expect('ID').value 1014 # CC: found = find param in params where param.name == paramName 1014 1015 found = false 1015 1016 for param in params 1016 if param.name ==paramName1017 if param.name == paramName 1017 1018 found = true 1018 1019 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]".') 1023 1022 .expect('MUST') 1024 1023 .expect('BE') 1025 1024 expectComma = false 1026 1025 while true 1027 if expectComma 1028 .expect('COMMA') 1026 if expectComma, .expect('COMMA') 1029 1027 param.constraints.add(.genericConstraint) 1030 if .optional('EOL') 1031 break 1028 if .optional('EOL'), break 1032 1029 expectComma = true 1033 1030 … … 1259 1256 .throwError('Encountered [opener.which] when expecting an identifier.') 1260 1257 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>() 1264 1261 name = opener.value to String 1265 1262 curBox = .curBox … … 1309 1306 # No additional specs like attributes, contracts or body 1310 1307 nothingMore = true 1311 if not hasIsNames 1312 isNames = List<of String>(_isNamesStack) 1308 if not hasIsNames, isNames = List<of String>(_isNamesStack) 1313 1309 attribs = AttributeList() 1314 1310 implementsType = nil to ITypeProxy? … … 1317 1313 # parse additional method declaration 1318 1314 nothingMore = false 1319 if not hasIsNames 1320 isNames = .isDeclNames1315 if not hasIsNames, isNames = .isDeclNames 1316 .genericConstraints(opener, genericParams) 1321 1317 attribs = .hasAttribs 1322 1318 implementsType = if(.optional('IMPLEMENTS'), .typeId, nil) … … 1333 1329 method = Initializer(token, .curBox, params, isNames, attribs, docString) 1334 1330 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) 1336 1332 if nothingMore 1337 1333 if not 'abstract' in isNames and not curBox inherits Interface -
cobra/trunk/Source/Members.cobra
r1662 r1711 665 665 def _bindInt is override 666 666 base._bindInt 667 # TODO: cleanup. try pushing this to .bindInt 667 668 .compiler.codeMemberStack.push(this) 668 669 try … … 1013 1014 1014 1015 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 1020 1026 1021 1027 def _bindImp is override -
cobra/trunk/Source/Node.cobra
r1708 r1711 419 419 _didStartBindInh = true 420 420 _isBindingInh = true 421 if .compiler 422 .compiler.nodeStack.push(this) 421 if .compiler, .compiler.nodeStack.push(this) 423 422 try 424 423 _didBindInhBase = false … … 428 427 finally 429 428 _finishChildReplacements 430 if .compiler 431 .compiler.nodeStack.pop 429 if .compiler, .compiler.nodeStack.pop 432 430 _isBindingInh = false 433 431 -
cobra/trunk/Source/SharpGenerator.cobra
r1702 r1711 1751 1751 sw.write('[returnType.sharpRef] [name][.sharpGenericParams]') 1752 1752 .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 1753 1759 if .isInterfaceMember and not .isExtensionMember 1754 1760 sw.write(';\n') 1755 1761 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) 1766 1767 1767 1768 def writeSharpImpHeader(sw as SharpWriter)
