示例#1
0
        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);
        }
示例#2
0
        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;
        }