Changeset 1781
- Timestamp:
- 11/28/08 15:11:01 (16 months ago)
- Location:
- cobra/trunk
- Files:
-
- 1 added
- 8 modified
-
Source/BackEndClr/SharpGenerator.cobra (modified) (3 diffs)
-
Source/Boxes.cobra (modified) (1 diff)
-
Source/Cobra.Lang/Misc.cobra (modified) (1 diff)
-
Source/CobraParser.cobra (modified) (1 diff)
-
Source/Container.cobra (modified) (1 diff)
-
Source/Expr.cobra (modified) (1 diff)
-
Source/TypeProxies.cobra (modified) (3 diffs)
-
Source/Types.cobra (modified) (21 diffs)
-
Tests/240-generics/500-misc/800-streams.cobra (added)
Legend:
- Unmodified
- Added
- Removed
-
cobra/trunk/Source/BackEndClr/SharpGenerator.cobra
r1768 r1781 789 789 return '0' 790 790 791 791 792 class PassThroughType 792 793 is partial … … 797 798 get sharpRef as String is override 798 799 return '/*passthrough*/object' 800 801 802 class StreamType 803 is partial 804 805 get sharpInit as String is override 806 return 'new EmptyStream<[.theWrappedType.sharpRef]>()' 807 808 get sharpRef as String is override 809 assert .didBindInh and .didBindInt 810 return '/*[.name]*/[.box.sharpRef]' 799 811 800 812 … … 1488 1500 sw.write(' = ') 1489 1501 _initExpr.writeSharpDef(sw) 1502 else if .type.isReference and not .type.nonNil inherits GenericParam 1503 sharpInit = .type.sharpInit 1504 if sharpInit.length 1505 sw.write(' = ') 1506 sw.write(sharpInit) 1490 1507 sw.write(';\n') 1491 1508 -
cobra/trunk/Source/Boxes.cobra
r1768 r1781 700 700 else if type.isGenericDef and .isGeneric and type is .genericDef 701 701 r = type.isAssignableTo(this) 702 if not r 703 if type inherits StreamType 704 r = .isAssignableTo(type.box to !) 702 705 return r 703 706 -
cobra/trunk/Source/Cobra.Lang/Misc.cobra
r1773 r1781 1 1 namespace Cobra.Lang 2 2 3 class EmptyStream<of T> 4 implements IEnumerable<of T> 5 6 def getEnumerator as IEnumerator<of T> 7 yield break 8 9 def getEnumerator as System.Collections.IEnumerator 10 implements System.Collections.IEnumerable 11 return .getEnumerator 12 3 13 interface ITreeBuilder 4 14 def indent -
cobra/trunk/Source/CobraParser.cobra
r1761 r1781 3252 3252 t = ArrayTypeIdentifier(bracket, t) 3253 3253 3254 # check for 'optional' aka 'can be nil' 3255 question = .optional('QUESTION') 3256 if question 3257 t = NilableTypeIdentifier(question, t) 3254 while true 3255 # check for 'optional' aka 'can be nil' 3256 if .optional('QUESTION') 3257 t = NilableTypeIdentifier(.last, t) 3258 3259 # check for 'stream' aka 'multiple' aka 'zero or more' aka 'enumerable' 3260 else if .optional('STAR') 3261 t = StreamTypeIdentifier(.last, t) 3262 3263 else 3264 break 3258 3265 3259 3266 return t to ! -
cobra/trunk/Source/Container.cobra
r1768 r1781 300 300 return false 301 301 302 get isUninitializedForLocalVars as bool 303 return .isReference 304 302 305 get innerType as IType? 303 306 return nil -
cobra/trunk/Source/Expr.cobra
r1769 r1781 352 352 def afterStatementBindImp is override 353 353 base.afterStatementBindImp 354 if not .type inherits NilableType 355 if .type.isReference 356 .throwError('Must initialize this non-nil object type, or change the type to nilable (suffix a ?).') 354 if .type.isUninitializedForLocalVars 355 .throwError('Must initialize this non-nil object type, or change the type to nilable (suffix with ?).') 357 356 358 357 -
cobra/trunk/Source/TypeProxies.cobra
r1759 r1781 357 357 return container.memberForName(.name) 358 358 Generics have to do more work, though. 359 So do types with funky names. 359 360 """ 360 361 return container.memberForName(.name) … … 446 447 class NilableTypeIdentifier 447 448 inherits WrappedTypeIdentifier 449 """ 450 Foo? 451 """ 448 452 449 453 def init(token as IToken, typeId as AbstractTypeIdentifier) … … 462 466 else 463 467 return m 468 469 470 class StreamTypeIdentifier 471 inherits WrappedTypeIdentifier 472 """ 473 Foo* 474 """ 475 476 def init(token as IToken, typeId as AbstractTypeIdentifier) 477 base.init(token, typeId) 478 479 def _resolveType as IType is override 480 t = StreamType(_typeId.realType) 481 t.bindInh 482 t.bindInt 483 return t 484 485 get name as String is override 486 return _typeId.name + '*' 464 487 465 488 -
cobra/trunk/Source/Types.cobra
r1768 r1781 306 306 307 307 def isAssignableTo(t as IType) as bool 308 return this ist or t.isSystemObjectClass308 return this == t or t.isSystemObjectClass 309 309 310 310 def isComparableTo(t as IType) as bool 311 return this ist311 return this == t 312 312 313 313 def isEquatableTo(t as IType) as bool 314 return this ist314 return this == t 315 315 316 316 def isDescendantOf(t as IType) as bool … … 320 320 return not _nativeType.isValueType 321 321 322 get isUninitializedForLocalVars as bool 323 return .isReference 324 322 325 def isStrictDescendantOf(t as IType) as bool 323 326 return this is not t and t.isSystemObjectClass … … 329 332 330 333 def greatestCommonDenominatorWith(type as IType) as IType 331 if type isthis334 if type == this 332 335 return this 333 336 else … … 505 508 """ 506 509 Return true if this type represents/is System.Type. 510 """ 511 512 get isUninitializedForLocalVars as bool 513 """ 514 Return true if a local var of this type is uninitialized without an explicit assignment. 515 The default implementation is typically: return .isReference 516 because non-nil reference types need an initial value. 507 517 """ 508 518 … … 624 634 return false 625 635 636 get isUninitializedForLocalVars as bool 637 return .isReference 638 626 639 def isComparableTo(t as IType) as bool 627 640 t = t.nonNil … … 636 649 def isEquatableTo(t as IType) as bool 637 650 t = t.nonNil 651 if this == t 652 return true 638 653 if .isAssignableTo(t) or t.isAssignableTo(this) 639 654 return true … … 667 682 668 683 def greatestCommonDenominatorWith(type as IType) as IType 669 if this istype684 if this == type 670 685 return this 671 686 if type inherits NilableType … … 689 704 .typeProvider 690 705 body 691 if type is .typeProvider.passThroughType 692 return true 693 if type is .typeProvider.dynamicType 694 return true 695 if type is .typeProvider.objectType 696 return true 697 # TODO: remove this: 698 if type inherits GenericParam 699 return true 706 if this == type, return true 707 if type is .typeProvider.passThroughType, return true 708 if type is .typeProvider.dynamicType, return true 709 if type is .typeProvider.objectType, return true 710 if type inherits GenericParam, return true # TODO: remove this: 700 711 # TODO: would this be needed if not for qualified types? 701 if type inherits WrappedType 712 if type inherits WrappedType # TODO: I think this is wrong as it covers VariType and StreamType. It should only be non-nil 702 713 return .isAssignableTo(type.theWrappedType to passthrough) # CC: bug with if-inherits changes the parameter type 703 714 return .isDescendantOf(type) … … 707 718 Returns true if this type is a subtype (direct or indirect) of type. 708 719 """ 709 if not .didBindInh 710 .bindInh 711 if this is type 712 return true 720 if not .didBindInh, .bindInh 721 if this == type, return true 713 722 curType = this to IType? 714 723 counter = 0 715 724 while true 716 if curType is type 717 return true 725 if curType == type, return true 718 726 curType = curType.superType 719 if curType is nil 720 break 727 if curType is nil, break 721 728 counter += 1 722 729 assert counter < 1000 … … 724 731 725 732 def isStrictDescendantOf(type as IType) as bool 726 if type isthis733 if type == this 727 734 return false 728 735 else … … 1041 1048 1042 1049 def greatestCommonDenominatorWith(type as IType) as IType is override 1043 if this istype1050 if this == type 1044 1051 return this 1045 1052 if type inherits NilableType … … 1137 1144 1138 1145 def isAssignableTo(type as IType) as bool 1139 if type isthis # common case1146 if type == this # common case 1140 1147 return true 1141 1148 if type inherits FloatType … … 1270 1277 1271 1278 def isAssignableTo(type as IType) as bool 1272 if type isthis # common case1279 if type == this # common case 1273 1280 return true 1274 1281 if type is .typeProvider.decimalType … … 1322 1329 return _wrappedType.isReference 1323 1330 1331 get isUninitializedForLocalVars as bool is override 1332 return false # because nil is fine for the default value 1333 1324 1334 # TODO: I think the following is appropriate, but come up with a test case for it first. 1325 1335 #get innerType … … 1354 1364 1355 1365 def greatestCommonDenominatorWith(type as IType) as IType is override 1356 if this istype1366 if this == type 1357 1367 return this 1358 1368 if type inherits NilType 1359 1369 return this 1360 1370 if type inherits NilableType 1361 if _wrappedType istype.nonNil1371 if _wrappedType == type.nonNil 1362 1372 return this 1363 1373 else … … 1380 1390 1381 1391 def isAssignableTo(type as IType) as bool is override 1382 if this istype, return true1392 if this == type, return true 1383 1393 if type is .compiler.passThroughType, return true 1384 1394 if type inherits NilableType, return true … … 1386 1396 1387 1397 def greatestCommonDenominatorWith(type as IType) as IType is override 1388 if this istype1398 if this == type 1389 1399 return this 1390 1400 if type inherits NilableType … … 1449 1459 1450 1460 1461 class StreamType 1462 is partial 1463 inherits WrappedType 1464 """ 1465 - Streams are portable between backends, whereas .NET's IEnumerable<of> and JVM's Iterable<of> are not. 1466 - Streams are two-way compatible with IEnumerable/Iterable: 1467 - Streams can be used whereever a compatible IEnumerable/Iterable is expected. 1468 - An IEnumerable/Iterable can be used whereever a compatible stream type is expected. 1469 - The term "compatible" means the same inner type: int* is compatible with IEnumerable<of int>/Iterable<of int>, but not IEnumerable<of String>/Iterable<of String> 1470 - Streams are an abstract type, so you cannot create them directly with a call on the type such as `int*()`. Instead, use a concrete class such as `List<of>` or `yield` results out of a method. 1471 - Streams are defaulted to be empty rather than nil. 1472 """ 1473 1474 var _box as Box? 1475 1476 def init(t as IType) 1477 base.init(t) 1478 1479 get englishName as String is override 1480 return 'stream of ' + _wrappedType.englishName 1481 1482 get box from var 1483 1484 get name as String is override 1485 return _wrappedType.name + '*' 1486 1487 get isReference as bool is override 1488 return true 1489 1490 get isUninitializedForLocalVars as bool is override 1491 return false # because streams get initialized to EmptyStream<of T> for convenience 1492 1493 get innerType as IType? is override 1494 return .theWrappedType 1495 1496 def isAssignableTo(type as IType) as bool is override 1497 return base.isAssignableTo(type) 1498 1499 def isComparableTo(b as IType) as bool is override 1500 return base.isComparableTo(b) 1501 1502 def isDescendantOf(type as IType) as bool 1503 return base.isDescendantOf(type) or .box.isDescendantOf(type) 1504 1505 def isEquatableTo(b as IType) as bool is override 1506 return base.isEquatableTo(b) 1507 1508 def memberForName(name as String) as IMember? is override 1509 return _box.memberForName(name) 1510 1511 def greatestCommonDenominatorWith(type as IType) as IType is override 1512 return base.greatestCommonDenominatorWith(type) 1513 1514 def _bindInh 1515 base._bindInh 1516 if .compiler # will be nil during unit tests 1517 _box = .compiler.enumerableOfType.constructedTypeFor([.theWrappedType]) 1518 _box.bindInh 1519 _superType = _box 1520 else if _superType is nil # TODO: is this really needed? 1521 _superType = .compiler.objectType 1522 1523 def _bindInt 1524 base._bindInt 1525 # TODO: why do we have to do this? 1526 if not .didBindInh 1527 .bindInh 1528 1529 1451 1530 class VoidType 1452 1531 is partial … … 1515 1594 1516 1595 get innerType as IType? is override 1517 return _wrappedType.innerType 1596 return _wrappedType.innerType # TODO: 2008-11-22, I think this should just be _wrappedType 1518 1597 1519 1598 def secondaryConstructedTypeFor(box as Box, gpToType as Dictionary<of GenericParam, IType>) as IType is override … … 1560 1639 1561 1640 get name as String is override 1562 return _wrappedType.name +r'[]'1641 return _wrappedType.name + r'[]' 1563 1642 1564 1643 def isAssignableTo(type as IType) as bool is override … … 1568 1647 if _wrappedType == type.theWrappedType 1569 1648 return true 1649 if type inherits StreamType 1650 return .isAssignableTo(type.box to !) 1570 1651 return false 1571 1652 1572 1653 def _bindInh 1573 1654 base._bindInh 1574 ienum = .compiler.enumerableOfType 1575 _superType = ienum.constructedTypeFor([.theWrappedType]) 1655 _superType = .compiler.enumerableOfType.constructedTypeFor([.theWrappedType]) 1576 1656 1577 1657 def memberForName(name as String) as IMember?
