internal static bool HasImplicitConversionTo(this TypeSymbol left, TypeSymbol right) { if (left.Equals(right)) { return(true); } // TODO: Need to be able to implicitly cast classes to base class and interfaces? if (left.IsUserDefined() || right.IsUserDefined()) { return(false); } if (left.Kind == SymbolKind.IntrinsicObjectType || right.Kind == SymbolKind.IntrinsicObjectType) { if (left.Kind == SymbolKind.IntrinsicObjectType && right.Kind == SymbolKind.IntrinsicObjectType) { var leftIntrinsicType = (IntrinsicObjectTypeSymbol)left; var rightIntrinsicType = (IntrinsicObjectTypeSymbol)right; if (leftIntrinsicType.PredefinedType == PredefinedObjectType.Sampler) { switch (rightIntrinsicType.PredefinedType) { case PredefinedObjectType.Sampler1D: case PredefinedObjectType.Sampler2D: case PredefinedObjectType.Sampler3D: case PredefinedObjectType.SamplerCube: case PredefinedObjectType.SamplerState: return(true); } } } return(false); } switch (left.Kind) { case SymbolKind.Array: switch (right.Kind) { case SymbolKind.Array: { var leftArray = (ArraySymbol)left; var rightArray = (ArraySymbol)right; return(leftArray.ValueType.HasImplicitConversionTo(rightArray.ValueType)); } default: return(false); } } if (left.Kind == SymbolKind.IntrinsicScalarType || right.Kind == SymbolKind.IntrinsicScalarType) { return(true); } switch (left.Kind) { case SymbolKind.IntrinsicVectorType: switch (right.Kind) { case SymbolKind.IntrinsicScalarType: return(true); case SymbolKind.IntrinsicVectorType: return(((IntrinsicVectorTypeSymbol)left).NumComponents == 1 || ((IntrinsicVectorTypeSymbol)left).NumComponents >= ((IntrinsicVectorTypeSymbol)right).NumComponents); case SymbolKind.IntrinsicMatrixType: { var leftVector = (IntrinsicVectorTypeSymbol)left; var rightMatrix = (IntrinsicMatrixTypeSymbol)right; return((leftVector.NumComponents >= rightMatrix.Cols && rightMatrix.Rows == 1) || (leftVector.NumComponents >= rightMatrix.Rows && rightMatrix.Cols == 1)); } case SymbolKind.Array: { var leftVector = (IntrinsicVectorTypeSymbol)left; var rightArray = (ArraySymbol)right; if (!leftVector.HasImplicitConversionTo(rightArray.ValueType)) { return(false); } if (rightArray.Dimension == null) { return(true); } return(leftVector.NumComponents >= rightArray.Dimension.Value); } } break; case SymbolKind.IntrinsicMatrixType: switch (right.Kind) { case SymbolKind.IntrinsicScalarType: return(true); case SymbolKind.IntrinsicVectorType: { var leftMatrix = (IntrinsicMatrixTypeSymbol)left; var rightVector = (IntrinsicVectorTypeSymbol)right; return((leftMatrix.Rows >= rightVector.NumComponents && leftMatrix.Cols == 1) || (leftMatrix.Cols >= rightVector.NumComponents && leftMatrix.Rows == 1)); } case SymbolKind.IntrinsicMatrixType: { var leftMatrix = (IntrinsicMatrixTypeSymbol)left; var rightMatrix = (IntrinsicMatrixTypeSymbol)right; return(leftMatrix.Rows >= rightMatrix.Rows && leftMatrix.Cols >= rightMatrix.Cols); } } break; } if (left.GetNumElements() >= right.GetNumElements()) { return(true); } return(false); }
internal static bool HasImplicitConversionTo(this TypeSymbol left, TypeSymbol right) { if (left.Equals(right)) return true; // TODO: Need to be able to implicitly cast classes to base class and interfaces? if (left.IsUserDefined() || right.IsUserDefined()) return false; if (left.Kind == SymbolKind.IntrinsicObjectType || right.Kind == SymbolKind.IntrinsicObjectType) { if (left.Kind == SymbolKind.IntrinsicObjectType && right.Kind == SymbolKind.IntrinsicObjectType) { var leftIntrinsicType = (IntrinsicObjectTypeSymbol) left; var rightIntrinsicType = (IntrinsicObjectTypeSymbol) right; if (leftIntrinsicType.PredefinedType == PredefinedObjectType.Sampler) { switch (rightIntrinsicType.PredefinedType) { case PredefinedObjectType.Sampler1D: case PredefinedObjectType.Sampler2D: case PredefinedObjectType.Sampler3D: case PredefinedObjectType.SamplerCube: case PredefinedObjectType.SamplerState: return true; } } } return false; } switch (left.Kind) { case SymbolKind.Array: switch (right.Kind) { case SymbolKind.Array: { var leftArray = (ArraySymbol) left; var rightArray = (ArraySymbol) right; return leftArray.ValueType.HasImplicitConversionTo(rightArray.ValueType); } default: return false; } } if (left.Kind == SymbolKind.IntrinsicScalarType || right.Kind == SymbolKind.IntrinsicScalarType) return true; switch (left.Kind) { case SymbolKind.IntrinsicVectorType: switch (right.Kind) { case SymbolKind.IntrinsicScalarType: return true; case SymbolKind.IntrinsicVectorType: return ((IntrinsicVectorTypeSymbol) left).NumComponents == 1 || ((IntrinsicVectorTypeSymbol) left).NumComponents >= ((IntrinsicVectorTypeSymbol) right).NumComponents; case SymbolKind.IntrinsicMatrixType: { var leftVector = (IntrinsicVectorTypeSymbol) left; var rightMatrix = (IntrinsicMatrixTypeSymbol) right; return (leftVector.NumComponents >= rightMatrix.Cols && rightMatrix.Rows == 1) || (leftVector.NumComponents >= rightMatrix.Rows && rightMatrix.Cols == 1); } case SymbolKind.Array: { var leftVector = (IntrinsicVectorTypeSymbol) left; var rightArray = (ArraySymbol) right; if (!leftVector.HasImplicitConversionTo(rightArray.ValueType)) return false; if (rightArray.Dimension == null) return true; return leftVector.NumComponents >= rightArray.Dimension.Value; } } break; case SymbolKind.IntrinsicMatrixType: switch (right.Kind) { case SymbolKind.IntrinsicScalarType: return true; case SymbolKind.IntrinsicVectorType: { var leftMatrix = (IntrinsicMatrixTypeSymbol) left; var rightVector = (IntrinsicVectorTypeSymbol) right; return (leftMatrix.Rows >= rightVector.NumComponents && leftMatrix.Cols == 1) || (leftMatrix.Cols >= rightVector.NumComponents && leftMatrix.Rows == 1); } case SymbolKind.IntrinsicMatrixType: { var leftMatrix = (IntrinsicMatrixTypeSymbol) left; var rightMatrix = (IntrinsicMatrixTypeSymbol) right; return leftMatrix.Rows >= rightMatrix.Rows && leftMatrix.Cols >= rightMatrix.Cols; } } break; } if (left.GetNumElements() >= right.GetNumElements()) return true; return false; }