public static EqualityExpressionPredicateCheck TryCreate(IEqualityExpression expression)
        {
            Contract.Requires(expression != null);

            var left = ExtractArgument(expression.LeftOperand);

            // TODO: right hand side could be any arbitrary expression, not only literals
            var right = expression.RightOperand as ICSharpLiteralExpression;

            if (left == null || right == null)
                return null;

            // The problem is, that for "person.Name != null" and
            // for "person != null" I should get "person"
            //var qualifierReference = left.QualifierExpression
            //    .With(x => x as IReferenceExpression);

            //string predicateArgument = (qualifierReference ?? left).NameIdentifier.Name;

            return new EqualityExpressionPredicateCheck(left)
            {
                EqualityType = expression.EqualityType,
                RightHandSide = right,
            };
        }
Beispiel #2
0
 public override IAssignableExpression VisitEqualityExpression(IEqualityExpression expr,
                                                               IList <IStatement> context)
 {
     return(new BinaryExpression
     {
         LeftOperand = ToSimpleExpression(expr.LeftOperand, context),
         Operator =
             expr.EqualityType == EqualityExpressionType.EQEQ ? BinaryOperator.Equal : BinaryOperator.NotEqual,
         RightOperand = ToSimpleExpression(expr.RightOperand, context)
     });
 }
Beispiel #3
0
        /// <summary>
        /// Compares two expressions.
        /// </summary>
        /// <param name="other">The other expression.</param>
        protected bool IsExpressionEqual(IEqualityExpression other)
        {
            Debug.Assert(other != null);

            bool Result = true;

            Result &= Expression.IsExpressionEqual((IExpression)LeftExpression, (IExpression)other.LeftExpression);
            Result &= Comparison == other.Comparison;
            Result &= Equality == other.Equality;
            Result &= Expression.IsExpressionEqual((IExpression)RightExpression, (IExpression)other.RightExpression);

            return(Result);
        }
Beispiel #4
0
        public static IEqualityComparer <T> EqualityComparer <T>(this IEqualityExpression <T> equality, IHashingExpression <T> hashing)
        {
            if (equality == null)
            {
                throw new NullReferenceException();
            }
            if (hashing == null)
            {
                throw new ArgumentNullException("hashing");
            }

            return(new CustomEqualityComparer <T>(equality.Expression.Compile(), hashing.Expression.Compile()));
        }
Beispiel #5
0
        public static IEqualityExpression <T> Equals <T, K>(this IEqualityExpression <T> expression, Expression <Func <T, K?> > selector, bool nullInequal)
            where K : struct, IEquatable <K>
        {
            if (expression == null)
            {
                throw new NullReferenceException();
            }
            if (selector == null)
            {
                throw new ArgumentNullException("selector");
            }

            return(new EqualityExpressionImpl <T>(EqualsCore(expression.Expression, selector, NullableEquality <K>(EquatableEquality <K>(), nullInequal))));
        }
            private void CheckNullComparisonWithUnityObject([NotNull] IEqualityExpression equalityExpressionParam, HotMethodAnalyzerContext context)
            {
                var reference = equalityExpressionParam.Reference;

                if (reference == null)
                {
                    return;
                }

                var isNullFound  = false;
                var leftOperand  = equalityExpressionParam.LeftOperand;
                var rightOperand = equalityExpressionParam.RightOperand;

                if (leftOperand == null || rightOperand == null)
                {
                    return;
                }

                IExpressionType expressionType = null;

                if (leftOperand.ConstantValue.IsNull())
                {
                    isNullFound    = true;
                    expressionType = rightOperand.GetExpressionType();
                }
                else if (rightOperand.ConstantValue.IsNull())
                {
                    isNullFound    = true;
                    expressionType = leftOperand.GetExpressionType();
                }

                if (!isNullFound)
                {
                    return;
                }

                var typeElement = expressionType.ToIType()?.GetTypeElement();

                if (typeElement == null)
                {
                    return;
                }

                if (typeElement.GetAllSuperTypes().Any(t => t.GetClrName().Equals(KnownTypes.Object)))
                {
                    context.MarkCurrentAsCostlyReachable();
                    myConsumer.AddHighlighting(new PerformanceCriticalCodeInvocationHighlighting(reference));
                }
            }
Beispiel #7
0
        public static IEqualityExpression <T> Equals <T, K>(this IEqualityExpression <T> expression, Expression <Func <T, K> > selector, Expression <Equality <K> > equality)
        {
            if (expression == null)
            {
                throw new NullReferenceException();
            }
            if (selector == null)
            {
                throw new ArgumentNullException("selector");
            }
            if (equality == null)
            {
                throw new ArgumentNullException("comparison");
            }

            return(new EqualityExpressionImpl <T>(EqualsCore(expression.Expression, selector, equality)));
        }
Beispiel #8
0
        public static IEqualityExpression <T> Equals <T, K>(this IEqualityExpression <T> expression, Expression <Func <T, K> > selector, IEqualityComparer <K> equalityComparer)
        {
            if (expression == null)
            {
                throw new NullReferenceException();
            }
            if (selector == null)
            {
                throw new ArgumentNullException("selector");
            }
            if (equalityComparer == null)
            {
                throw new ArgumentNullException("equalityComparer");
            }

            return(new EqualityExpressionImpl <T>(EqualsCore(expression.Expression, selector, ComparerEquality(equalityComparer))));
        }
Beispiel #9
0
        private bool IsInNeedOfFixing(IEqualityExpression binexpr)
        {
            if (binexpr.EqualityType != EqualityExpressionType.EQEQ)
            {
                return(false);
            }

            // Is the right hand side a string literal?
            var right = binexpr.RightOperand as ILiteralExpression;

            if (right == null || !right.ToTreeNode().GetTokenType().IsStringLiteral)
            {
                return(false);
            }


            // Is the left hand side a call to Enum.ToString followed by a zero or more ToUpper,ToLower & Trim calls?
            var left = binexpr.LeftOperand as IInvocationExpression;

            if (left == null)
            {
                return(false);
            }

            var visitor = new MyIsExpressionStringCallsOnAnEnum();

            left.Accept(visitor);

            if (visitor.Found)
            {
                var enumSymbolTable = visitor.FoundEnumReference.GetReferenceSymbolTable(true).Filter(new MyFilter());

                foreach (ISymbolInfo info in enumSymbolTable.AllSymbolInfos())
                {
                    if (string.Compare(info.ShortName, right.ConstantValue.Value.ToString(), true) == 0)
                    {
                        ReplacementText = visitor.EnumReferenceName + " == " + visitor.EnumDeclaredName + "." + info.ShortName;
                        return(true);
                    }
                    // TODO: Technically, a case mismatch should result in a "conditional is always false" error.
                }
            }
            return(false);
        }
Beispiel #10
0
        static ICSharpExpression TryGetOtherOperand(
            [NotNull] IEqualityExpression equalityExpression,
            EqualityExpressionType equalityType,
            [NotNull] TokenNodeType operandNodeType)
        {
            if (equalityExpression.EqualityType == equalityType)
            {
                if (IsLiteral(equalityExpression.RightOperand, operandNodeType))
                {
                    return(equalityExpression.LeftOperand);
                }

                if (IsLiteral(equalityExpression.LeftOperand, operandNodeType))
                {
                    return(equalityExpression.RightOperand);
                }
            }

            return(null);
        }
        private bool IsInNeedOfFixing(IEqualityExpression binexpr)
        {
            if(binexpr.EqualityType != EqualityExpressionType.EQEQ) return false;

            // Is the right hand side a string literal?
            var right = binexpr.RightOperand as ILiteralExpression;
            if (right == null || !right.ToTreeNode().GetTokenType().IsStringLiteral)
            {
                return false;
            }

            // Is the left hand side a call to Enum.ToString followed by a zero or more ToUpper,ToLower & Trim calls?
            var left = binexpr.LeftOperand as IInvocationExpression;
            if(left == null)
            {
                return false;
            }

            var visitor = new MyIsExpressionStringCallsOnAnEnum();
            left.Accept( visitor );

            if (visitor.Found)
            {
                var enumSymbolTable = visitor.FoundEnumReference.GetReferenceSymbolTable(true).Filter(new MyFilter());

                foreach (ISymbolInfo info in enumSymbolTable.AllSymbolInfos())
                {
                    if (string.Compare(info.ShortName, right.ConstantValue.Value.ToString(), true) == 0)
                    {
                        ReplacementText = visitor.EnumReferenceName + " == " + visitor.EnumDeclaredName + "." + info.ShortName;
                        return true;
                    }
                    // TODO: Technically, a case mismatch should result in a "conditional is always false" error.
                }
            }
            return false;
        }
        /// <summary>
        /// Negates the equality expression.
        /// </summary>
        /// <param name="factory">
        /// The factory.
        /// </param>
        /// <param name="equalityExpression">
        /// The equality expression.
        /// </param>
        private static void NegateEqualityExpression(CSharpElementFactory factory, IEqualityExpression equalityExpression)
        {
            var operatorSign = equalityExpression.OperatorSign.GetText();

              operatorSign = operatorSign == "==" ? "!=" : "==";

              var expression = factory.CreateExpression(string.Format("{0} {1} {2}", equalityExpression.LeftOperand.GetText(), operatorSign, equalityExpression.RightOperand.GetText()));

              equalityExpression.ReplaceBy(expression);
        }
Beispiel #13
0
 public ConvertToCompareTagQuickFix(ExplicitTagStringComparisonWarning warning)
 {
     myExpression         = warning.EqualityExpression;
     myRewriteLeftOperand = warning.LeftOperandIsTagReference;
 }
Beispiel #14
0
 public ExplicitTagStringComparisonWarning(IEqualityExpression expression, bool leftOperandIsTagReference)
 {
     Expression = expression;
     LeftOperandIsTagReference = leftOperandIsTagReference;
 }
Beispiel #15
0
        /// <summary>
        /// Finds the matching nodes of a <see cref="IEqualityExpression"/>.
        /// </summary>
        /// <param name="node">The agent expression to check.</param>
        /// <param name="errorList">The list of errors found.</param>
        /// <param name="resolvedResult">The expression result types upon return.</param>
        /// <param name="resolvedException">Exceptions the expression can throw upon return.</param>
        /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param>
        /// <param name="expressionConstant">The constant value upon return, if any.</param>
        public static bool ResolveCompilerReferences(IEqualityExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant)
        {
            resolvedResult     = null;
            resolvedException  = null;
            constantSourceList = new SealableList <IExpression>();
            expressionConstant = NeutralLanguageConstant.NotConstant;

            IExpression LeftExpression  = (IExpression)node.LeftExpression;
            IExpression RightExpression = (IExpression)node.RightExpression;
            IClass      EmbeddingClass  = node.EmbeddingClass;
            IResultType LeftResult      = LeftExpression.ResolvedResult.Item;
            IResultType RightResult     = RightExpression.ResolvedResult.Item;

            if (LeftResult.Count != RightResult.Count)
            {
                errorList.AddError(new ErrorExpressionResultMismatch(node));
                return(false);
            }

            if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, node, out ITypeName ResultTypeName, out ICompiledType ResultType))
            {
                errorList.AddError(new ErrorBooleanTypeMissing(node));
                return(false);
            }

            if (LeftResult.Count > 1)
            {
                int MismatchingResultCount = 0;
                foreach (IExpressionType LeftItem in LeftResult)
                {
                    ICompiledType LeftExpressionType = LeftItem.ValueType;

                    bool MatchingNameFound = false;
                    foreach (IExpressionType RightItem in RightResult)
                    {
                        if (LeftItem.Name == RightItem.Name)
                        {
                            MatchingNameFound = true;
                            ICompiledType RightExpressionType = RightItem.ValueType;

                            if (!ObjectType.TypeConformToBase(LeftExpressionType, RightExpressionType, isConversionAllowed: true) && !ObjectType.TypeConformToBase(RightExpressionType, LeftExpressionType, isConversionAllowed: true))
                            {
                                MismatchingResultCount++;
                            }

                            break;
                        }
                    }

                    if (!MatchingNameFound)
                    {
                        MismatchingResultCount++;
                    }
                }

                if (MismatchingResultCount > 0)
                {
                    errorList.AddError(new ErrorExpressionResultMismatch(node));
                    return(false);
                }
            }

            resolvedResult = new ResultType(ResultTypeName, ResultType, string.Empty);

            constantSourceList.Add(LeftExpression);
            constantSourceList.Add(RightExpression);

            resolvedException = new ResultException();
            ResultException.Merge(resolvedException, LeftExpression.ResolvedException);
            ResultException.Merge(resolvedException, RightExpression.ResolvedException);

#if COVERAGE
            Debug.Assert(node.IsComplex);
#endif

            return(true);
        }
 /// <summary>
 /// Creates a new C# expression.
 /// </summary>
 /// <param name="context">The creation context.</param>
 /// <param name="source">The Easly expression from which the C# expression is created.</param>
 public static ICSharpEqualityExpression Create(ICSharpContext context, IEqualityExpression source)
 {
     return(new CSharpEqualityExpression(context, source));
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="CSharpEqualityExpression"/> class.
 /// </summary>
 /// <param name="context">The creation context.</param>
 /// <param name="source">The Easly expression from which the C# expression is created.</param>
 protected CSharpEqualityExpression(ICSharpContext context, IEqualityExpression source)
     : base(context, source)
 {
     LeftExpression  = Create(context, (IExpression)source.LeftExpression);
     RightExpression = Create(context, (IExpression)source.RightExpression);
 }
Beispiel #18
0
 public override void VisitEqualityExpression(IEqualityExpression equalityExpressionParam, HotMethodAnalyzerContext context)
 {
     CheckNullComparisonWithUnityObject(equalityExpressionParam, context);
 }
Beispiel #19
0
            private void CheckNullComparisonWithUnityObject([NotNull] IEqualityExpression equalityExpressionParam, HotMethodAnalyzerContext context)
            {
                var reference = equalityExpressionParam.Reference;

                if (reference == null)
                {
                    return;
                }

                var isNullFound  = false;
                var leftOperand  = equalityExpressionParam.LeftOperand;
                var rightOperand = equalityExpressionParam.RightOperand;

                if (leftOperand == null || rightOperand == null)
                {
                    return;
                }

                ICSharpExpression expression = null;

                if (leftOperand.ConstantValue.IsNull())
                {
                    isNullFound = true;
                    expression  = rightOperand;
                }
                else if (rightOperand.ConstantValue.IsNull())
                {
                    isNullFound = true;
                    expression  = leftOperand;
                }

                if (!isNullFound)
                {
                    return;
                }

                var typeElement = expression.GetExpressionType().ToIType()?.GetTypeElement();

                if (typeElement == null)
                {
                    return;
                }

                if (typeElement.GetAllSuperTypes().Any(t => t.GetClrName().Equals(KnownTypes.Object)))
                {
                    context.MarkCurrentAsCostly();

                    var suffix = equalityExpressionParam.EqualityType == EqualityExpressionType.NE ? "NotNull" : "Null";

                    string baseName = null;
                    if (expression is IReferenceExpression referenceExpression)
                    {
                        baseName = referenceExpression.NameIdentifier.Name;
                    }
                    else
                    {
                        baseName = typeElement.ShortName;
                    }

                    var variableName = "is" + baseName + suffix;
                    myConsumer.AddHighlighting(new PerformanceNullComparisonHighlighting(equalityExpressionParam, variableName, reference));
                }
            }
        public static bool IsNullComparisonWithUnityObject(IEqualityExpression equalityExpression, out string possibleName)
        {
            possibleName = null;
            var reference = equalityExpression.Reference;

            if (reference == null)
            {
                return(false);
            }

            var isNullFound  = false;
            var leftOperand  = equalityExpression.LeftOperand;
            var rightOperand = equalityExpression.RightOperand;

            if (leftOperand == null || rightOperand == null)
            {
                return(false);
            }

            ICSharpExpression expression = null;

            if (leftOperand.ConstantValue.IsNull())
            {
                isNullFound = true;
                expression  = rightOperand;
            }
            else if (rightOperand.ConstantValue.IsNull())
            {
                isNullFound = true;
                expression  = leftOperand;
            }

            if (!isNullFound)
            {
                return(false);
            }

            var typeElement = expression.GetExpressionType().ToIType()?.GetTypeElement();

            if (typeElement == null)
            {
                return(false);
            }

            if (typeElement.GetAllSuperTypes().Any(t => t.GetClrName().Equals(KnownTypes.Object)))
            {
                var suffix = equalityExpression.EqualityType == EqualityExpressionType.NE ? "NotNull" : "Null";

                string baseName;
                if (expression is IReferenceExpression referenceExpression)
                {
                    baseName = referenceExpression.NameIdentifier.Name;
                }
                else
                {
                    baseName = typeElement.ShortName;
                }

                possibleName = "is" + baseName + suffix;
                return(true);
            }

            return(false);
        }