public override Node Visit(AssignmentExpression assignmentExpression)
        {
            var  variable           = GetUniform(assignmentExpression.Target);
            bool isMemberExpression = assignmentExpression.Target is MemberReferenceExpression;

            if (variable != null)
            {
                // Default == operator is the only write only operators
                if (assignmentExpression.Operator == AssignmentOperator.Default && !uniformReadList.Contains(variable) && !this.UniformUsedWriteFirstList.Contains(variable))
                {
                    // Handle the case where the assignment operator is partial like vect.xy = 5; and later vect.zw += 6;
                    // In this case, the variable is considered as read and write (and not only write first)
                    if (isMemberExpression)
                    {
                        var variableType = variable.Type.ResolveType();

                        if (variableType is VectorType || variableType is MatrixType)
                        {
                            var dim = Math.Max(TypeBase.GetDimensionSize(variableType, 0), TypeBase.GetDimensionSize(variableType, 1));

                            var memberRef       = assignmentExpression.Target as MemberReferenceExpression;
                            var numberOfMembers = memberRef.Member.Text.Length;

                            // If the variable is a global uniform, non static/const and is not already in the list used then
                            if (numberOfMembers < dim)
                            {
                                if (!uniformReadList.Contains(variable))
                                {
                                    uniformReadList.Add(variable);
                                }
                            }
                            else
                            {
                                UniformUsedWriteFirstList.Add(variable);
                            }
                        }
                    }
                    else
                    {
                        UniformUsedWriteFirstList.Add(variable);
                    }
                }
                if (assignmentExpression.Operator != AssignmentOperator.Default)
                {
                    if (!UniformReadWriteList.Contains(variable))
                    {
                        UniformReadWriteList.Add(variable);
                    }
                }
            }

            return(assignmentExpression);
        }
Exemple #2
0
        /// <summary>
        /// Tests the arguments of the method
        /// </summary>
        /// <param name="argTypeBase">the argument typebase</param>
        /// <param name="expectedTypeBase">the expected typebase</param>
        /// <param name="argType">the argument type</param>
        /// <param name="expectedType">the expected type</param>
        /// <param name="score">the score of the overload</param>
        /// <returns>true if the overload is correct, false otherwise</returns>
        protected virtual bool TestMethodInvocationArgument(TypeBase argTypeBase, TypeBase expectedTypeBase, TypeBase argType, TypeBase expectedType, ref int score)
        {
            var validOverload = true;

            // If Scalar, Vector or Matrix, check types
            if (TypeBase.HasDimensions(argType) && TypeBase.HasDimensions(expectedType))
            {
                if (argType != expectedType)
                {
                    int argDim1      = TypeBase.GetDimensionSize(argType, 0);
                    int argDim2      = TypeBase.GetDimensionSize(argType, 1);
                    int expectedDim1 = TypeBase.GetDimensionSize(expectedType, 0);
                    int expectedDim2 = TypeBase.GetDimensionSize(expectedType, 1);

                    // float3<=>float1x3 and float3<=>float3x1 implicit conversion are allowed,
                    // but float3x1<=>float1x3 should not be allowed
                    // float3<=>float1x3 and float1x1<=>float1<=>float
                    if (argDim1 == expectedDim1 && argDim2 == expectedDim2)
                    {
                        score++;
                    }
                    else if (((argType is VectorType && expectedType is MatrixType) || (argType is MatrixType && expectedType is VectorType)) &&
                             (argDim1 == expectedDim2 && argDim2 == expectedDim1))
                    {
                        // float3<=>float3x1
                        score++;
                    }
                    else if (argDim1 == 1 && argDim2 == 1)
                    {
                        // allow float=>float3x2 and float=>float3
                        score += 10; // +10 for scalar=>vector or scalar=>matrix expansion
                    }
                    else if (argDim1 >= expectedDim1 && argDim2 >= expectedDim2)
                    {
                        // Truncation
                        // +100 for truncation (by rank difference)
                        score += 100 * (argDim1 + argDim2 - expectedDim1 - expectedDim2);
                    }
                    else
                    {
                        // Could not find any matching implicit conversion
                        validOverload = false;
                    }
                }
            }
            else if (argType is ArrayType && expectedType is ArrayType)
            {
                var argArrayType      = (ArrayType)argType;
                var expectedArrayType = (ArrayType)expectedType;

                if (argArrayType != expectedArrayType)
                {
                    validOverload = false;
                }
            }
            else if (argType is StructType && expectedType is StructType)
            {
                var argStructType      = (StructType)argType;
                var expectedStructType = (StructType)expectedType;

                if (argStructType.Name != expectedStructType.Name)
                {
                    validOverload = false;
                }
            }
            else if (!((argType is ObjectType && expectedType is ObjectType) || (argType is StructType && expectedType is StructType)))
            {
                // Could not find any matching implicit conversion
                validOverload = false;
            }

            return(validOverload);
        }