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, }; }
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) }); }
/// <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); }
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())); }
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)); } }
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))); }
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)))); }
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); }
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); }
public ConvertToCompareTagQuickFix(ExplicitTagStringComparisonWarning warning) { myExpression = warning.EqualityExpression; myRewriteLeftOperand = warning.LeftOperandIsTagReference; }
public ExplicitTagStringComparisonWarning(IEqualityExpression expression, bool leftOperandIsTagReference) { Expression = expression; LeftOperandIsTagReference = leftOperandIsTagReference; }
/// <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); }
public override void VisitEqualityExpression(IEqualityExpression equalityExpressionParam, HotMethodAnalyzerContext context) { CheckNullComparisonWithUnityObject(equalityExpressionParam, context); }
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); }