Changeset 1706
- Timestamp:
- 10/25/08 01:25:20 (2 months ago)
- Location:
- cobra/trunk/Source
- Files:
-
- 3 modified
-
BinaryOpExpr.cobra (modified) (2 diffs)
-
Expr.cobra (modified) (3 diffs)
-
Types.cobra (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
cobra/trunk/Source/BinaryOpExpr.cobra
r1662 r1706 525 525 else if .op in ['IS', 'ISNOT'] 526 526 # Essentially "is" and "is not" are for reference types. Give a warning when used for value types. 527 if not TypeUtil.isDynamicOrPassThrough(leftType) and not TypeUtil.isDynamicOrPassThrough(rightType)527 if not leftType.isDynamicOrPassThrough and not rightType.isDynamicOrPassThrough 528 528 opName = if(.op=='IS', 'is', 'is not') 529 529 altName = if(.op=='IS', '==', '<>') … … 533 533 .compiler.warning(this, 'Both the left and right sides of "[opName]" are value types ("[leftType.name]" and "[rightType.name]"), but "[opName]" applies to reference types. Use "[altName]" instead.') 534 534 # interestingly, I don't think the following ever happen in practice... 535 else if not leftType.isReference and not TypeUtil.isNilableAndDescendantOf(rightType,leftType)535 else if not leftType.isReference and not rightType.isNilableAndDescendantOf(leftType) 536 536 .compiler.warning(this, 'The left side of "[opName]" is a value type ("[leftType.name]") while the right side is an incompatible reference type ("[rightType.name]").') 537 else if not rightType.isReference and not TypeUtil.isNilableAndDescendantOf(leftType,rightType)537 else if not rightType.isReference and not leftType.isNilableAndDescendantOf(rightType) 538 538 .compiler.warning(this, 'The right side of "[opName]" is a value type ("[rightType.name]") while the left side is an incompatible reference type ("[leftType.name]").') 539 539 else -
cobra/trunk/Source/Expr.cobra
r1662 r1706 181 181 body 182 182 base._bindImp 183 184 def _isSequence(type as IType) as bool185 if type inherits NilableType186 return _isSequence(type.theWrappedType to passthrough)187 # TODO: check for ISliceable which would have a .getSlice188 if type.isDescendantOf(.compiler.stringType)189 return true190 # if type.isDescendantOf(.compiler.arrayType)191 if type inherits ArrayType192 return true193 if type.isDescendantOf(.compiler.ilistType)194 return true195 genericList = .compiler.listOfType196 if type.isDescendantOf(genericList)197 return true198 if type inherits Box199 if type.genericDef is genericList200 return true201 genericIList = .compiler.ilistOfType202 if type.isDescendantOf(genericIList)203 return true204 if type inherits Box205 if type.genericDef is genericIList206 return true207 if type.isDynamic208 return true209 return false210 183 211 184 def _suggestionsMessage(suggs as List<of String>) as String … … 799 772 _what.bindImp # bind first because it may be needed for type inference 800 773 whatType = _what.type to ! 801 if not whatType.isDescendantOf(.compiler.enumerableType) and not _isSequence(whatType) # TODO: can probably drop _isSequence774 if not whatType.isDescendantOf(.compiler.enumerableType) and not whatType.isSequenceLike # TODO: can probably drop .isSequenceLike 802 775 .throwError('Cannot enumerate values of type "[whatType.name]". You can enumerate anything enumerable (IEnumerable, IList, arrays, strings, etc.).') 803 776 _var = .bindVar(_nameExpr) … … 1739 1712 .compiler.recordError(ne) 1740 1713 success 1741 if not _ isSequence(_target.type to !)1714 if not _target.type.isSequenceLike 1742 1715 .throwError('Cannot slice values of type "[_target.type.name]". You can slice strings, arrays, IList and IList<of>.') 1743 1716 if _start -
cobra/trunk/Source/Types.cobra
r1704 r1706 1605 1605 extend IType 1606 1606 1607 def isDynamicOrPassThrough as bool 1608 return this inherits DynamicType or this inherits PassThroughType 1609 1610 def isNilableAndDescendantOf(otherType as IType) as bool 1611 return this inherits NilableType and ((this to NilableType).theWrappedType).isDescendantOf(otherType) 1612 1613 def isSequenceLike as bool 1614 """ 1615 Returns true if the receiver is like a sequence, such as being an actual array, list, string, or a nilable version thereof. 1616 The dynamic type will also return true because at compile-time, dynamic is considered to be like everything. 1617 Requires Node.getCompiler 1618 """ 1619 type = this 1620 if type inherits NilableType 1621 return type.theWrappedType.isSequenceLike 1622 # TODO: check for ISliceable which would have a .getSlice 1623 tp = Node.getCompiler # 'tp' for 'type provider' 1624 if type.isDescendantOf(tp.stringType) 1625 return true 1626 # if type.isDescendantOf(tp.arrayType) 1627 if type inherits ArrayType 1628 return true 1629 if type.isDescendantOf(tp.ilistType) 1630 return true 1631 genericList = tp.listOfType 1632 if type.isDescendantOf(genericList) 1633 return true 1634 if type inherits Box 1635 if type.genericDef is genericList 1636 return true 1637 genericIList = tp.ilistOfType 1638 if type.isDescendantOf(genericIList) 1639 return true 1640 if type inherits Box 1641 if type.genericDef is genericIList 1642 return true 1643 if type.isDynamic 1644 return true 1645 return false 1646 1607 1647 def isDictionaryLike as bool 1608 1648 """ … … 1614 1654 if type inherits NilableType 1615 1655 return type.theWrappedType.isDictionaryLike 1616 tp = Node.getCompiler # TODO? expand ITypeProvider to cover idictionaryType, dictionaryOfType, idictionaryOfType1656 tp = Node.getCompiler # 'tp' for 'type provider' # TODO? expand ITypeProvider to cover idictionaryType, dictionaryOfType, idictionaryOfType 1617 1657 if type.isDescendantOf(tp.idictionaryType) 1618 1658 return true … … 1635 1675 1636 1676 class TypeUtil 1677 """ 1678 If the utility involves primarily one instance of IType, or an instance of IType is the logical 1679 "receiver" of a message, then add the utility method to "extend IType" above. 1680 """ 1637 1681 1638 # TODO: should be interface extension on IType1639 1640 1682 shared 1641 1642 def isDynamicOrPassThrough(t as IType) as bool1643 return t inherits DynamicType or t inherits PassThroughType1644 1645 def isNilableAndDescendantOf(t1 as IType, t2 as IType) as bool1646 return t1 inherits NilableType and ((t1 to NilableType).theWrappedType).isDescendantOf(t2)1647 1683 1648 1684 def dictionaryOf(genericParams as List<of IType>, typeArgs as IList<of IType>) as Dictionary<of GenericParam, IType>
