internal static string GetResolvedString(SyntaxNodeAnalysisContext context, ExpressionSyntax expression, ref bool isNotConstant)
        {
            if (expression == null)
                return string.Empty;

            string result;
            if (_conditionalWeakTable.TryGetValue(expression, out result))
            {
                return result;
            }

            switch (expression.Kind())
            {
                case SyntaxKind.AddExpression:
                    var addExpression = (BinaryExpressionSyntax)expression;
                    result = GetResolvedString(context, addExpression.Left, ref isNotConstant) + GetResolvedString(context, addExpression.Right, ref isNotConstant);
                    break;
                case SyntaxKind.IdentifierName:
                    var value = context.SemanticModel.GetConstantValue(expression);
                    result = value.HasValue ? value.Value as string : string.Empty;
                    break;
                case SyntaxKind.StringLiteralExpression:
                    var literalExpression = (LiteralExpressionSyntax)expression;
                    result = literalExpression.Token.Value as string;
                    break;
                default:
                    isNotConstant = true;
                    result = string.Empty;
                    break;
            }

            _conditionalWeakTable.Add(expression, result);
            return result;
        }
 static bool CanBeNull(SemanticModel semanticModel, ExpressionSyntax expression, CancellationToken cancellationToken)
 {
     var info = semanticModel.GetTypeInfo(expression, cancellationToken);
     if (info.ConvertedType.IsReferenceType || info.ConvertedType.IsNullableType())
         return true;
     return false;
 }
        void Check(SyntaxNodeAnalysisContext nodeContext, ExpressionSyntax condition)
        {
            if (condition == null)
                return;

            if (condition.IsKind(SyntaxKind.TrueLiteralExpression) || condition.IsKind(SyntaxKind.FalseLiteralExpression))
                return;

            var resolveResult = nodeContext.SemanticModel.GetConstantValue(condition);
            if (!resolveResult.HasValue || !(resolveResult.Value is bool))
                return;

            var value = (bool)resolveResult.Value;

            nodeContext.ReportDiagnostic(Diagnostic.Create(
                descriptor.Id,
                descriptor.Category,
                string.Format(descriptor.MessageFormat.ToString(), value),
                descriptor.DefaultSeverity,
                descriptor.DefaultSeverity,
                descriptor.IsEnabledByDefault,
                4,
                descriptor.Title,
                descriptor.Description,
                descriptor.HelpLinkUri,
                condition.GetLocation(),
                null,
                new[] { value.ToString() }
            ));
        }
 public static bool IsComplexExpression(ExpressionSyntax expr)
 {
     var loc = expr.GetLocation().GetLineSpan();
     return loc.StartLinePosition.Line != loc.EndLinePosition.Line ||
         expr is ConditionalExpressionSyntax ||
         expr is BinaryExpressionSyntax;
 }
 private static bool CheckExpression(ExpressionSyntax constant, ExpressionSyntax modulus,
     out int constantValue)
 {
     return SillyBitwiseOperation.TryGetConstantIntValue(constant, out constantValue) &&
            constantValue != 0 &&
            ExpressionIsModulus(modulus);
 }
 /// <param name="typeSyntax">The argument to typeof.</param>
 /// <param name="allowedMap">
 /// Keys are GenericNameSyntax nodes representing unbound generic types.
 /// Values are false if the node should result in an error and true otherwise.
 /// </param>
 /// <param name="isUnboundGenericType">True if no constructed generic type was encountered.</param>
 public static void Visit(ExpressionSyntax typeSyntax, out Dictionary<GenericNameSyntax, bool> allowedMap, out bool isUnboundGenericType)
 {
     OpenTypeVisitor visitor = new OpenTypeVisitor();
     visitor.Visit(typeSyntax);
     allowedMap = visitor.allowedMap;
     isUnboundGenericType = visitor.seenGeneric && !visitor.seenConstructed;
 }
示例#7
0
        private static bool IsExpectedActualAssertion(ExpressionSyntax expression)
        {
            var expr = expression as MemberAccessExpressionSyntax;
            if (expr == null)
            {
                return false;
            }

            var identifier = expr.Expression as IdentifierNameSyntax;
            if (identifier == null)
            {
                return false;
            }

            if (identifier.Identifier.Text != "Assert")
            {
                return false;
            }

            var methodName = expr.Name.Identifier.Text;

            if (methodName == "Equal"  // Xunit
                || methodName == "AreEqual"  // NUnit, MSTest
                || methodName == "NotEqual"  // Xunit
                || methodName == "AreNotEqual"  // NUnit, MSTest
                )
            {
                return true;
            }

            return false;
        }
示例#8
0
 internal static void BasicNameVerification(ExpressionSyntax nameTree, string name)
 {
     // Verification of the change
     Assert.IsType(typeof(IdentifierNameSyntax), nameTree);
     var genericName = nameTree as IdentifierNameSyntax;
     Assert.Equal(genericName.ToString(), name);
 }
示例#9
0
        /// <summary>
        /// Analyzes if type information is obvious to the reader by simply looking at the assignment expression.
        /// </summary>
        /// <remarks>
        /// <paramref name="typeInDeclaration"/> accepts null, to be able to cater to codegen features
        /// that are about to generate a local declaration and do not have this information to pass in.
        /// Things (like analyzers) that do have a local declaration already, should pass this in.
        /// </remarks>
        public static bool IsTypeApparentInAssignmentExpression(
            TypeStylePreference stylePreferences,
            ExpressionSyntax initializerExpression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken,
            ITypeSymbol typeInDeclaration = null)
        {
            // default(type)
            if (initializerExpression.IsKind(SyntaxKind.DefaultExpression))
            {
                return true;
            }

            // literals, use var if options allow usage here.
            if (initializerExpression.IsAnyLiteralExpression())
            {
                return stylePreferences.HasFlag(TypeStylePreference.ImplicitTypeForIntrinsicTypes);
            }

            // constructor invocations cases:
            //      = new type();
            if (initializerExpression.IsKind(SyntaxKind.ObjectCreationExpression) &&
                !initializerExpression.IsKind(SyntaxKind.AnonymousObjectCreationExpression))
            {
                return true;
            }

            // explicit conversion cases: 
            //      (type)expr, expr is type, expr as type
            if (initializerExpression.IsKind(SyntaxKind.CastExpression) ||
                initializerExpression.IsKind(SyntaxKind.IsExpression) ||
                initializerExpression.IsKind(SyntaxKind.AsExpression))
            {
                return true;
            }

            // other Conversion cases:
            //      a. conversion with helpers like: int.Parse methods
            //      b. types that implement IConvertible and then invoking .ToType()
            //      c. System.Convert.Totype()
            var memberName = GetRightmostInvocationExpression(initializerExpression).GetRightmostName();
            if (memberName == null)
            {
                return false;
            }

            var methodSymbol = semanticModel.GetSymbolInfo(memberName, cancellationToken).Symbol as IMethodSymbol;
            if (methodSymbol == null)
            {
                return false;
            }

            if (memberName.IsRightSideOfDot())
            {
                var containingTypeName = memberName.GetLeftSideOfDot();
                return IsPossibleCreationOrConversionMethod(methodSymbol, typeInDeclaration, semanticModel, containingTypeName, cancellationToken);
            }

            return false;
        }
 internal static bool? GetBool(ExpressionSyntax trueExpression)
 {
     var pExpr = trueExpression as LiteralExpressionSyntax;
     if (pExpr == null || !(pExpr.Token.Value is bool))
         return null;
     return (bool)pExpr.Token.Value;
 }
示例#11
0
 internal static void ArrayNameVerification(ExpressionSyntax nameTree, string arrayName, int numRanks)
 {
     Assert.IsType(typeof(ArrayTypeSyntax), nameTree);
     var arrayType = nameTree as ArrayTypeSyntax;
     Assert.Equal(arrayType.ElementType.ToString(), arrayName);
     Assert.Equal(arrayType.RankSpecifiers.Count(), numRanks);
 }
        public static bool ContainsCheck(ExpressionSyntax expr)
        {
            if (expr is InvocationExpressionSyntax)
              {
            var i = (InvocationExpressionSyntax)expr;

            if (i.ArgumentList.Arguments.Count == 1)
            {
              // include some special methods from QuickGraph
              return new string[] { "Contains", "ContainsVertex", "ContainsEdge", "ContainsKey" }.Any(n => n.Equals(SimpleMethodName(i)));
            }
            else
            {
              return false;
            }
              }
              else if (expr is PrefixUnaryExpressionSyntax && expr.Kind == SyntaxKind.LogicalNotExpression)
              {
            return ContainsCheck(((PrefixUnaryExpressionSyntax)expr).Operand);
              }
              else
              {
            return false;
              }
        }
            // TODO: Add support for Expression<T>
            private IEnumerable<ITypeSymbol> GetTypes(ExpressionSyntax expression)
            {
                if (seenExpressionGetType.Add(expression))
                {
                    IEnumerable<ITypeSymbol> types;

                    // BUG: (vladres) Are following expressions parenthesized correctly?
                    // BUG:
                    // BUG: (davip) It is parenthesized incorrectly. This problem was introduced in Changeset 822325 when 
                    // BUG: this method was changed from returning a single ITypeSymbol to returning an IEnumerable<ITypeSymbol> 
                    // BUG: to better deal with overloads. The old version was:
                    // BUG: 
                    // BUG:     if (!IsUnusableType(type = GetTypeSimple(expression)) ||
                    // BUG:         !IsUnusableType(type = GetTypeComplex(expression)))
                    // BUG:           { return type; }
                    // BUG: 
                    // BUG: The intent is to only use *usable* types, whether simple or complex. I have confirmed this intent with Ravi, who made the change. 
                    // BUG: 
                    // BUG: Note that the current implementation of GetTypesComplex and GetTypesSimple already ensure the returned value 
                    // BUG: is a usable type, so there should not (currently) be any observable effect of this logic error.
                    // BUG:
                    // BUG: (vladres) Please remove this comment once the bug is fixed.
                    if ((types = GetTypesSimple(expression).Where(t => !IsUnusableType(t))).Any() ||
                        (types = GetTypesComplex(expression)).Where(t => !IsUnusableType(t)).Any())
                    {
                        return types;
                    }
                }

                return SpecializedCollections.EmptyEnumerable<ITypeSymbol>();
            }
		private Document IntroduceLocalDeclarationIntoLambda(
			SemanticDocument document,
			ExpressionSyntax expression,
			IdentifierNameSyntax newLocalName,
			LocalDeclarationStatementSyntax declarationStatement,
			SyntaxNode oldLambda,
			bool allOccurrences,
			CancellationToken cancellationToken)
		{
			var oldBody = oldLambda is ParenthesizedLambdaExpressionSyntax
				? (ExpressionSyntax)((ParenthesizedLambdaExpressionSyntax)oldLambda).Body
			                                                                        : (ExpressionSyntax)((SimpleLambdaExpressionSyntax)oldLambda).Body;

			var rewrittenBody = Rewrite(
				document, expression, newLocalName, document, oldBody, allOccurrences, cancellationToken);

			var delegateType = document.SemanticModel.GetTypeInfo(oldLambda, cancellationToken).ConvertedType as INamedTypeSymbol;

			var newBody = delegateType != null && delegateType.DelegateInvokeMethod != null && delegateType.DelegateInvokeMethod.ReturnsVoid
			                                                  ? SyntaxFactory.Block(declarationStatement)
			                                                  : SyntaxFactory.Block(declarationStatement, SyntaxFactory.ReturnStatement(rewrittenBody));

			newBody = newBody.WithAdditionalAnnotations(Formatter.Annotation);

			var newLambda = oldLambda is ParenthesizedLambdaExpressionSyntax
				? ((ParenthesizedLambdaExpressionSyntax)oldLambda).WithBody(newBody)
			                                                      : (SyntaxNode)((SimpleLambdaExpressionSyntax)oldLambda).WithBody(newBody);

			var newRoot = document.Root.ReplaceNode(oldLambda, newLambda);
			return document.Document.WithSyntaxRoot(newRoot);
		}
示例#15
0
        /// <summary>
        /// The Enumerable.Last method will only special case indexable types that implement <see cref="IList{T}" />.  Types 
        /// which implement only <see cref="IReadOnlyList{T}"/> will be treated the same as IEnumerable{T} and go through a 
        /// full enumeration.  This method identifies such types.
        /// 
        /// At this point it only identifies <see cref="IReadOnlyList{T}"/> directly but could easily be extended to support
        /// any type which has an index and count property.  
        /// </summary>
        private bool IsTypeWithInefficientLinqMethods(SyntaxNodeAnalysisContext context, ExpressionSyntax targetSyntax, ITypeSymbol readonlyListType, ITypeSymbol listType)
        {
            var targetTypeInfo = context.SemanticModel.GetTypeInfo(targetSyntax);
            if (targetTypeInfo.Type == null)
            {
                return false;
            }

            var targetType = targetTypeInfo.Type;

            // If this type is simply IReadOnlyList<T> then no further checking is needed.  
            if (targetType.TypeKind == TypeKind.Interface && targetType.OriginalDefinition.Equals(readonlyListType))
            {
                return true;
            }

            bool implementsReadOnlyList = false;
            bool implementsList = false;
            foreach (var current in targetType.AllInterfaces)
            {
                if (current.OriginalDefinition.Equals(readonlyListType))
                {
                    implementsReadOnlyList = true;
                }

                if (current.OriginalDefinition.Equals(listType))
                {
                    implementsList = true;
                }
            }

            return implementsReadOnlyList && !implementsList;
        }
示例#16
0
        protected MemberSyntax(ExpressionSyntax expression)
        {
            if (expression == null)
                throw new ArgumentNullException("expression");

            Expression = expression;
        }
            private IEnumerable<ITypeSymbol> GetTypesSimple(ExpressionSyntax expression)
            {
                if (expression != null)
                {
                    var typeInfo = SemanticModel.GetTypeInfo(expression, CancellationToken);
                    var symbolInfo = SemanticModel.GetSymbolInfo(expression, CancellationToken);

                    if (symbolInfo.CandidateReason != CandidateReason.WrongArity)
                    {
                        ITypeSymbol type = typeInfo.Type;

                        // If it bound to a method, try to get the Action/Func form of that method.
                        if (type == null &&
                            symbolInfo.GetAllSymbols().Count() == 1 &&
                            symbolInfo.GetAllSymbols().First().Kind == SymbolKind.Method)
                        {
                            var method = symbolInfo.GetAllSymbols().First();
                            type = method.ConvertToType(this.Compilation);
                        }

                        if (IsUsableTypeFunc(type))
                        {
                            return SpecializedCollections.SingletonEnumerable(type);
                        }
                    }
                }

                return SpecializedCollections.EmptyEnumerable<ITypeSymbol>();
            }
示例#18
0
        /// <summary>
        /// There are two kinds of deconstruction-assignments which this binding handles: tuple and non-tuple.
        ///
        /// Returns a BoundDeconstructionAssignmentOperator with a list of deconstruction steps and assignment steps.
        /// Deconstruct steps for tuples have no invocation to Deconstruct, but steps for non-tuples do.
        /// The caller is responsible for releasing all the ArrayBuilders in checkedVariables.
        /// </summary>
        private BoundDeconstructionAssignmentOperator BindDeconstructionAssignment(
                                                        CSharpSyntaxNode node,
                                                        ExpressionSyntax right,
                                                        ArrayBuilder<DeconstructionVariable> checkedVariables,
                                                        DiagnosticBag diagnostics,
                                                        bool isDeclaration,
                                                        BoundDeconstructValuePlaceholder rhsPlaceholder = null)
        {
            // receiver for first Deconstruct step
            var boundRHS = rhsPlaceholder ?? BindValue(right, diagnostics, BindValueKind.RValue);

            boundRHS = FixTupleLiteral(checkedVariables, boundRHS, node, diagnostics);

            if ((object)boundRHS.Type == null)
            {
                // we could still not infer a type for the RHS
                FailRemainingInferences(checkedVariables, diagnostics);

                return new BoundDeconstructionAssignmentOperator(
                            node, isDeclaration, FlattenDeconstructVariables(checkedVariables), boundRHS,
                            ImmutableArray<BoundDeconstructionDeconstructStep>.Empty,
                            ImmutableArray<BoundDeconstructionAssignmentStep>.Empty,
                            ImmutableArray<BoundDeconstructionAssignmentStep>.Empty,
                            ImmutableArray<BoundDeconstructionConstructionStep>.Empty,
                            GetSpecialType(SpecialType.System_Void, diagnostics, node),
                            hasErrors: true);
            }

            var deconstructionSteps = ArrayBuilder<BoundDeconstructionDeconstructStep>.GetInstance(1);
            var conversionSteps = ArrayBuilder<BoundDeconstructionAssignmentStep>.GetInstance(1);
            var assignmentSteps = ArrayBuilder<BoundDeconstructionAssignmentStep>.GetInstance(1);
            var constructionStepsOpt = isDeclaration ? null : ArrayBuilder<BoundDeconstructionConstructionStep>.GetInstance(1);

            bool hasErrors = !DeconstructIntoSteps(
                                    new BoundDeconstructValuePlaceholder(boundRHS.Syntax, boundRHS.Type),
                                    node,
                                    diagnostics,
                                    checkedVariables,
                                    deconstructionSteps,
                                    conversionSteps,
                                    assignmentSteps,
                                    constructionStepsOpt);

            TypeSymbol returnType = isDeclaration ?
                                            GetSpecialType(SpecialType.System_Void, diagnostics, node) :
                                            hasErrors ?
                                                CreateErrorType() :
                                                constructionStepsOpt.Last().OutputPlaceholder.Type;

            var deconstructions = deconstructionSteps.ToImmutableAndFree();
            var conversions = conversionSteps.ToImmutableAndFree();
            var assignments = assignmentSteps.ToImmutableAndFree();
            var constructions = isDeclaration ? default(ImmutableArray<BoundDeconstructionConstructionStep>) : constructionStepsOpt.ToImmutableAndFree();

            FailRemainingInferences(checkedVariables, diagnostics);

            return new BoundDeconstructionAssignmentOperator(
                            node, isDeclaration, FlattenDeconstructVariables(checkedVariables), boundRHS,
                            deconstructions, conversions, assignments, constructions, returnType, hasErrors: hasErrors);
        }
        private static bool IsRequiredCastForReferenceEqualityComparison(ITypeSymbol outerType, CastExpressionSyntax castExpression, SemanticModel semanticModel, out ExpressionSyntax other)
        {
            if (outerType.SpecialType == SpecialType.System_Object)
            {
                var expression = castExpression.WalkUpParentheses();
                var parentNode = expression.Parent;
                if (parentNode.IsKind(SyntaxKind.EqualsExpression) || parentNode.IsKind(SyntaxKind.NotEqualsExpression))
                {
                    // Reference comparison.
                    var binaryExpression = (BinaryExpressionSyntax)parentNode;
                    other = binaryExpression.Left == expression ?
                        binaryExpression.Right :
                        binaryExpression.Left;

                    // Explicit cast not required if we are comparing with type parameter with a class constraint.
                    var otherType = semanticModel.GetTypeInfo(other).Type;
                    if (otherType != null && otherType.TypeKind != TypeKind.TypeParameter)
                    {
                        return !other.WalkDownParentheses().IsKind(SyntaxKind.CastExpression);
                    }
                }
            }

            other = null;
            return false;
        }
 internal static bool CheckExceptionType(SemanticModel model, ObjectCreationExpressionSyntax objectCreateExpression, out ExpressionSyntax paramNode)
 {
     paramNode = null;
     var type = model.GetTypeInfo(objectCreateExpression).Type;
     if (type == null)
         return false;
     if (type.Name == typeof(ArgumentException).Name)
     {
         if (objectCreateExpression.ArgumentList.Arguments.Count >= 2)
         {
             paramNode = objectCreateExpression.ArgumentList.Arguments[1].Expression;
         }
         return paramNode != null;
     }
     if (type.Name == typeof(ArgumentNullException).Name ||
         type.Name == typeof(ArgumentOutOfRangeException).Name ||
         type.Name == "DuplicateWaitObjectException")
     {
         if (objectCreateExpression.ArgumentList.Arguments.Count >= 1)
         {
             paramNode = objectCreateExpression.ArgumentList.Arguments[0].Expression;
         }
         return paramNode != null;
     }
     return false;
 }
        public CallSyntax(ExpressionSyntax expression, IEnumerable<ExpressionSyntax> arguments)
        {
            Requires.NotNull(expression, nameof(expression));

            Expression = expression;
            Arguments = arguments.ToList();
        }
示例#22
0
        internal void CollectLocalsFromDeconstruction(
            ExpressionSyntax declaration,
            LocalDeclarationKind kind,
            ArrayBuilder<LocalSymbol> locals,
            SyntaxNode deconstructionStatement,
            Binder enclosingBinderOpt = null)
        {
            switch (declaration.Kind())
            {
                case SyntaxKind.TupleExpression:
                    {
                        var tuple = (TupleExpressionSyntax)declaration;
                        foreach (var arg in tuple.Arguments)
                        {
                            CollectLocalsFromDeconstruction(arg.Expression, kind, locals, deconstructionStatement, enclosingBinderOpt);
                        }
                        break;
                    }
                case SyntaxKind.DeclarationExpression:
                    {
                        var declarationExpression = (DeclarationExpressionSyntax)declaration;
                        CollectLocalsFromDeconstruction(
                            declarationExpression.Designation, declarationExpression.Type,
                            kind, locals, deconstructionStatement, enclosingBinderOpt);

                        break;
                    }
                case SyntaxKind.IdentifierName:
                    break;
                default:
                    throw ExceptionUtilities.UnexpectedValue(declaration.Kind());
            }
        }
 private bool IsCorrectReturnType(ExpressionSyntax expression, SemanticModel semanticModel)
 {
     INamedTypeSymbol taskType = null;
     INamedTypeSymbol returnType = null;
     return TryGetTypes(expression, semanticModel, out taskType, out returnType) &&
     semanticModel.Compilation.ClassifyConversion(taskType, returnType).Exists;
 }
 static CodeAction AddIsNaNIssue(Document document, SemanticModel semanticModel, SyntaxNode root, BinaryExpressionSyntax node, ExpressionSyntax argExpr, string floatType)
 {
     return CodeActionFactory.Create(node.Span, DiagnosticSeverity.Warning, string.Format(node.IsKind(SyntaxKind.EqualsExpression) ? "Replace with '{0}.IsNaN(...)' call" : "Replace with '!{0}.IsNaN(...)' call", floatType), token =>
     {
         SyntaxNode newRoot;
         ExpressionSyntax expr;
         var arguments = new SeparatedSyntaxList<ArgumentSyntax>();
         arguments = arguments.Add(SyntaxFactory.Argument(argExpr));
         expr = SyntaxFactory.InvocationExpression(
             SyntaxFactory.MemberAccessExpression(
                 SyntaxKind.SimpleMemberAccessExpression,
                 SyntaxFactory.ParseExpression(floatType),
                 SyntaxFactory.IdentifierName("IsNaN")
             ),
             SyntaxFactory.ArgumentList(
                 arguments
             )
         );
         if (node.IsKind(SyntaxKind.NotEqualsExpression))
             expr = SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, expr);
         expr = expr.WithAdditionalAnnotations(Formatter.Annotation);
         newRoot = root.ReplaceNode((SyntaxNode)node, expr);
         return Task.FromResult(document.WithSyntaxRoot(newRoot));
     });
 }
 public QueryUnboundLambdaState(UnboundLambda unbound, Binder binder, RangeVariableMap rangeVariableMap, ImmutableArray<RangeVariableSymbol> parameters, ExpressionSyntax body)
     : this(unbound, binder, rangeVariableMap, parameters, (LambdaSymbol lambdaSymbol, ExecutableCodeBinder lambdaBodyBinder, DiagnosticBag diagnostics) =>
 {
     BoundExpression expression = lambdaBodyBinder.BindValue(body, diagnostics, BindValueKind.RValue);
     return lambdaBodyBinder.WrapExpressionLambdaBody(expression, body, diagnostics);
 })
 { }
            private bool IsConstant(ExpressionSyntax expression)
            {
                switch (expression.Kind())
                {
                    case SyntaxKind.CharacterLiteralExpression:
                    case SyntaxKind.FalseLiteralExpression:
                    case SyntaxKind.NullLiteralExpression:
                    case SyntaxKind.NumericLiteralExpression:
                    case SyntaxKind.StringLiteralExpression:
                    case SyntaxKind.TrueLiteralExpression:
                        {
                            return true;
                        }

                    case SyntaxKind.SimpleMemberAccessExpression:
                    case SyntaxKind.IdentifierName:
                        {
                            ISymbol symbol = _model.GetSymbolInfo(expression).Symbol;

                            if (symbol != null && symbol.Kind == SymbolKind.Field)
                            {
                                return ((IFieldSymbol)symbol).IsConst;
                            }

                            break;
                        }
                }

                return false;
            }
示例#27
0
        public override FlatOperand Resolve(ExpressionSyntax expression, ArgumentListSyntax argumentList, TypeInfo result_type, SymbolInfo si, FlatOperand into_lvalue, Function function, List<FlatStatement> instructions)
        {
            FlatOperand fop_subject;
            if (expression is IdentifierNameSyntax)
            {
                // typeof this
                fop_subject = FlatOperand.ThisRef(FlatValue.FromType(result_type.ConvertedType));
            }
            else if (expression is MemberAccessExpressionSyntax)
            {
                MemberAccessExpressionSyntax meas = (MemberAccessExpressionSyntax)expression;

                fop_subject = function.ResolveExpression(meas.Expression, null, instructions);
            }
            else
            {
                throw new NotImplementedException("GetMetaTable on expression type " + expression.GetType().ToString());
            }

            if (into_lvalue == null)
            {
                FlatOperand fop_register = function.AllocateRegister("");
                into_lvalue = fop_register.GetLValue(function, instructions);
            }
            instructions.Add(FlatStatement.GETMETATABLE(into_lvalue, fop_subject));
            return into_lvalue.AsRValue(FlatValue.Table());
        }
        private INamedTypeSymbol FindSymbol(ExpressionSyntax expression)
        {
            while (true)
            {
                var parenthesizedExpression = expression as ParenthesizedExpressionSyntax;
                if (parenthesizedExpression != null)
                {
                    expression = parenthesizedExpression.Expression;
                    continue;
                }

                var castExpression = expression as CastExpressionSyntax;
                if (castExpression != null)
                {
                    return semanticModel.GetTypeInfo(castExpression.Type).Type as INamedTypeSymbol;
                }

                if (expression is InvocationExpressionSyntax)//Handled by invocationanalzyer
                {
                    return null;
                }

                var localSymbol = semanticModel.GetSymbolInfo(expression).Symbol as ILocalSymbol;
                return localSymbol?.Type as INamedTypeSymbol;
            }
        }
        public static bool IsComplexCondition(ExpressionSyntax expr)
        {
            var loc = expr.GetLocation().GetLineSpan();
            if (loc.StartLinePosition.Line != loc.EndLinePosition.Line)
                return true;

            if (expr is LiteralExpressionSyntax || expr is IdentifierNameSyntax || expr is MemberAccessExpressionSyntax || expr is InvocationExpressionSyntax)
                return false;

            var pexpr = expr as ParenthesizedExpressionSyntax;
            if (pexpr != null)
                return IsComplexCondition(pexpr.Expression);

            var uOp = expr as PrefixUnaryExpressionSyntax;
            if (uOp != null)
                return IsComplexCondition(uOp.Operand);

            var bop = expr as BinaryExpressionSyntax;
            if (bop == null)
                return true;
            return !(bop.IsKind(SyntaxKind.GreaterThanExpression) ||
                bop.IsKind(SyntaxKind.GreaterThanOrEqualExpression) ||
                bop.IsKind(SyntaxKind.EqualsExpression) ||
                bop.IsKind(SyntaxKind.NotEqualsExpression) ||
                bop.IsKind(SyntaxKind.LessThanExpression) ||
                bop.IsKind(SyntaxKind.LessThanOrEqualExpression));
        }
示例#30
0
        internal void CollectLocalsFromDeconstruction(
            ExpressionSyntax declaration,
            LocalDeclarationKind kind,
            ArrayBuilder<LocalSymbol> locals,
            SyntaxNode deconstructionStatement,
            Binder enclosingBinderOpt = null)
        {
            switch (declaration.Kind())
            {
                case SyntaxKind.TupleExpression:
                    {
                        var tuple = (TupleExpressionSyntax)declaration;
                        foreach (var arg in tuple.Arguments)
                        {
                            CollectLocalsFromDeconstruction(arg.Expression, kind, locals, deconstructionStatement, enclosingBinderOpt);
                        }
                        break;
                    }
                case SyntaxKind.DeclarationExpression:
                    {
                        var declarationExpression = (DeclarationExpressionSyntax)declaration;
                        CollectLocalsFromDeconstruction(
                            declarationExpression.Designation, declarationExpression.Type,
                            kind, locals, deconstructionStatement, enclosingBinderOpt);

                        break;
                    }
                case SyntaxKind.IdentifierName:
                    break;
                default:
                    // In broken code, we can have an arbitrary expression here. Collect its expression variables.
                    ExpressionVariableFinder.FindExpressionVariables(this, locals, declaration);
                    break;
            }
        }
示例#31
0
        private void ReportDiagnostic(ExpressionSyntax expression, TypeInfo typeInfo)
        {
            var diagnostic = Diagnostic.Create(StringFormatArgumentImplicitToStringAnalyzer.Rule, expression.GetLocation(), typeInfo.Type.ToDisplayString());

            this.context.ReportDiagnostic(diagnostic);
        }
示例#32
0
        private static ExpressionSyntax LogicallyInvertImpl(
            ExpressionSyntax expression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (expression == null)
            {
                return(expression);
            }

            switch (expression.Kind())
            {
            case SyntaxKind.SimpleMemberAccessExpression:
            case SyntaxKind.InvocationExpression:
            case SyntaxKind.ElementAccessExpression:
            case SyntaxKind.PostIncrementExpression:
            case SyntaxKind.PostDecrementExpression:
            case SyntaxKind.ObjectCreationExpression:
            case SyntaxKind.AnonymousObjectCreationExpression:
            case SyntaxKind.TypeOfExpression:
            case SyntaxKind.DefaultExpression:
            case SyntaxKind.CheckedExpression:
            case SyntaxKind.UncheckedExpression:
            case SyntaxKind.IdentifierName:
            {
                return(DefaultInvert(expression));
            }

            case SyntaxKind.LogicalNotExpression:
            {
                return(((PrefixUnaryExpressionSyntax)expression).Operand);
            }

            case SyntaxKind.CastExpression:
            {
                return(DefaultInvert(expression));
            }

            case SyntaxKind.LessThanExpression:
            case SyntaxKind.LessThanOrEqualExpression:
            case SyntaxKind.GreaterThanExpression:
            case SyntaxKind.GreaterThanOrEqualExpression:
            {
                return((semanticModel != null)
                            ? InvertLessThanOrGreaterThan((BinaryExpressionSyntax)expression, semanticModel, cancellationToken)
                            : DefaultInvert(expression));
            }

            case SyntaxKind.IsExpression:
            case SyntaxKind.AsExpression:
            case SyntaxKind.IsPatternExpression:
            {
                return(DefaultInvert(expression));
            }

            case SyntaxKind.EqualsExpression:
            case SyntaxKind.NotEqualsExpression:
            {
                return(InvertBinaryExpression((BinaryExpressionSyntax)expression));
            }

            case SyntaxKind.BitwiseAndExpression:
            {
                return(InvertBinaryExpression((BinaryExpressionSyntax)expression, semanticModel, cancellationToken));
            }

            case SyntaxKind.ExclusiveOrExpression:
            {
                return(DefaultInvert(expression));
            }

            case SyntaxKind.BitwiseOrExpression:
            case SyntaxKind.LogicalOrExpression:
            case SyntaxKind.LogicalAndExpression:
            {
                return(InvertBinaryExpression((BinaryExpressionSyntax)expression, semanticModel, cancellationToken));
            }

            case SyntaxKind.ConditionalExpression:
            {
                return(InvertConditionalExpression((ConditionalExpressionSyntax)expression, semanticModel, cancellationToken));
            }

            case SyntaxKind.SimpleAssignmentExpression:
            case SyntaxKind.AddAssignmentExpression:
            case SyntaxKind.SubtractAssignmentExpression:
            case SyntaxKind.MultiplyAssignmentExpression:
            case SyntaxKind.DivideAssignmentExpression:
            case SyntaxKind.ModuloAssignmentExpression:
            case SyntaxKind.AndAssignmentExpression:
            case SyntaxKind.ExclusiveOrAssignmentExpression:
            case SyntaxKind.OrAssignmentExpression:
            case SyntaxKind.LeftShiftAssignmentExpression:
            case SyntaxKind.RightShiftAssignmentExpression:
            {
                return(DefaultInvert(expression));
            }

            case SyntaxKind.TrueLiteralExpression:
            {
                return(FalseLiteralExpression());
            }

            case SyntaxKind.FalseLiteralExpression:
            {
                return(TrueLiteralExpression());
            }

            case SyntaxKind.ParenthesizedExpression:
            {
                var parenthesizedExpression = (ParenthesizedExpressionSyntax)expression;

                ExpressionSyntax expression2 = parenthesizedExpression.Expression;

                if (expression2 == null)
                {
                    return(parenthesizedExpression);
                }

                if (expression2.IsMissing)
                {
                    return(parenthesizedExpression);
                }

                ExpressionSyntax newExpression = LogicallyInvertImpl(expression2, semanticModel, cancellationToken);

                newExpression = newExpression.WithTriviaFrom(expression2);

                return(parenthesizedExpression.WithExpression(newExpression));
            }

            case SyntaxKind.AwaitExpression:
            {
                return(DefaultInvert(expression));
            }
            }

            Debug.Fail($"Logical inversion of unknown kind '{expression.Kind()}'");

            return(DefaultInvert(expression));
        }
示例#33
0
 /// <summary>
 /// Returns new expression that represents logical inversion of the specified expression.
 /// </summary>
 /// <param name="expression"></param>
 /// <param name="cancellationToken"></param>
 public static ExpressionSyntax LogicallyInvert(
     ExpressionSyntax expression,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     return(LogicallyInvert(expression, semanticModel: null, cancellationToken));
 }
 private static bool IsArgumentOnExceptionList(ExpressionSyntax argumentExpression)
 {
     return(argumentExpression != null &&
            ArgumentExceptionSyntaxKinds.Any(argumentExpression.IsKind));
 }
示例#35
0
        private static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context)
        {
            var conditionalExpression = (ConditionalExpressionSyntax)context.Node;

            ExpressionSyntax condition = conditionalExpression.Condition;

            if (condition.IsMissing)
            {
                return;
            }

            ExpressionSyntax whenTrue = conditionalExpression.WhenTrue;

            if (whenTrue.IsMissing)
            {
                return;
            }

            if (SyntaxTriviaAnalysis.IsTokenFollowedWithNewLineAndNotPrecededWithNewLine(condition, conditionalExpression.QuestionToken, whenTrue))
            {
                if (!AnalyzerOptions.AddNewLineAfterConditionalOperatorInsteadOfBeforeIt.IsEnabled(context))
                {
                    ReportDiagnostic(DiagnosticRules.AddNewLineBeforeConditionalOperatorInsteadOfAfterItOrViceVersa, conditionalExpression.QuestionToken, ImmutableDictionary <string, string> .Empty);
                    return;
                }
            }
            else if (SyntaxTriviaAnalysis.IsTokenPrecededWithNewLineAndNotFollowedWithNewLine(condition, conditionalExpression.QuestionToken, whenTrue))
            {
                if (AnalyzerOptions.AddNewLineAfterConditionalOperatorInsteadOfBeforeIt.IsEnabled(context))
                {
                    ReportDiagnostic(DiagnosticRules.ReportOnly.AddNewLineAfterConditionalOperatorInsteadOfBeforeIt, conditionalExpression.QuestionToken, DiagnosticProperties.AnalyzerOption_Invert);
                    return;
                }
            }

            ExpressionSyntax whenFalse = conditionalExpression.WhenFalse;

            if (!whenFalse.IsMissing)
            {
                if (SyntaxTriviaAnalysis.IsTokenFollowedWithNewLineAndNotPrecededWithNewLine(whenTrue, conditionalExpression.ColonToken, whenFalse))
                {
                    if (!AnalyzerOptions.AddNewLineAfterConditionalOperatorInsteadOfBeforeIt.IsEnabled(context))
                    {
                        ReportDiagnostic(DiagnosticRules.AddNewLineBeforeConditionalOperatorInsteadOfAfterItOrViceVersa, conditionalExpression.ColonToken, ImmutableDictionary <string, string> .Empty);
                    }
                }
                else if (SyntaxTriviaAnalysis.IsTokenPrecededWithNewLineAndNotFollowedWithNewLine(whenTrue, conditionalExpression.ColonToken, whenFalse))
                {
                    if (AnalyzerOptions.AddNewLineAfterConditionalOperatorInsteadOfBeforeIt.IsEnabled(context))
                    {
                        ReportDiagnostic(DiagnosticRules.ReportOnly.AddNewLineAfterConditionalOperatorInsteadOfBeforeIt, conditionalExpression.ColonToken, DiagnosticProperties.AnalyzerOption_Invert);
                    }
                }
            }

            void ReportDiagnostic(DiagnosticDescriptor descriptor, SyntaxToken token, ImmutableDictionary <string, string> properties)
            {
                DiagnosticHelpers.ReportDiagnostic(
                    context,
                    descriptor,
                    Location.Create(token.SyntaxTree, token.Span.WithLength(0)),
                    properties: properties,
                    AnalyzerOptions.AddNewLineAfterConditionalOperatorInsteadOfBeforeIt);
            }
        }
 private static bool IsSanitizedQuery(ExpressionSyntax expression, SemanticModel model)
 {
     return(model.GetConstantValue(expression).HasValue);
 }
 static bool IsMethodRequiringAwait(ExpressionSyntax call, SyntaxNodeAnalysisContext context) =>
 context.SemanticModel.GetSymbolInfo(call).Symbol is IMethodSymbol methodSymbol &&
示例#38
0
        public IEnumerable <StatementSyntax> AddComponent(TranslationContext context, ExpressionSyntax entity,
                                                          ExpressionSyntax componentDeclaration, TypeSyntax componentTypeSyntax, bool isSharedComponent)
        {
            string expressionId = isSharedComponent
                ? nameof(EntityManager.AddSharedComponentData)
                : nameof(EntityManager.AddComponentData);

            yield return(ExpressionStatement(RoslynBuilder.MethodInvocation(
                                                 expressionId,
                                                 IdentifierName(nameof(EntityManager)),
                                                 new[]
            {
                Argument(entity),
                Argument(componentDeclaration)
            },
                                                 new[] { componentTypeSyntax })));
        }
示例#39
0
 public void BuildCriteria(RoslynEcsTranslator translator, TranslationContext context, ExpressionSyntax entity,
                           IEnumerable <CriteriaModel> criteriaModels)
 {
     this.BuildCriteria(
         translator,
         context,
         entity,
         criteriaModels.Where(x => x.Criteria.Any()),
         ContinueStatement()
         );
 }
示例#40
0
 public IEnumerable <StatementSyntax> RemoveComponent(TranslationContext context, ExpressionSyntax entity,
                                                      string componentName)
 {
     yield return(ExpressionStatement(RoslynBuilder.MethodInvocation(
                                          nameof(EntityManager.RemoveComponent),
                                          IdentifierName(nameof(EntityManager)),
                                          new[] { Argument(entity) },
                                          new[] { IdentifierName(Identifier(componentName)) })));
 }
		public static bool AreConditionsEqual(ExpressionSyntax cond1, ExpressionSyntax cond2)
		{
			if (cond1 == null || cond2 == null)
				return false;
			return cond1.SkipParens().IsEquivalentTo(cond2.SkipParens(), true);
		}
示例#42
0
 public SyntaxNode SendEvent(TranslationContext translatorContext, ExpressionSyntax entity, Type eventType, ExpressionSyntax newEventSyntax)
 {
     throw new NotImplementedException();
 }
示例#43
0
        private ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded)
        {
            var vbConvertedType = _semanticModel.GetTypeInfo(vbNode).ConvertedType;

            switch (conversionKind)
            {
            case TypeConversionKind.Unknown:
            case TypeConversionKind.Identity:
                return(addParenthesisIfNeeded ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode) : csNode);

            case TypeConversionKind.DestructiveCast:
            case TypeConversionKind.NonDestructiveCast:
                var typeName = (TypeSyntax)_csSyntaxGenerator.TypeExpression(vbConvertedType);
                if (csNode is CastExpressionSyntax cast && cast.Type.IsEquivalentTo(typeName))
                {
                    return(csNode);
                }
                return(ValidSyntaxFactory.CastExpression(typeName, csNode));

            case TypeConversionKind.Conversion:
                return(AddExplicitConvertTo(vbNode, csNode, vbConvertedType));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
		/// <summary>
		/// Inverts a boolean condition. Note: The condition object can be frozen (from AST) it's cloned internally.
		/// </summary>
		/// <param name="condition">The condition to invert.</param>
		public static ExpressionSyntax InvertCondition(ExpressionSyntax condition)
		{
			return InvertConditionInternal(condition);
		}
示例#45
0
        public ExpressionSyntax AddExplicitConvertTo(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, ITypeSymbol type)
        {
            var displayType = type.ToMinimalDisplayString(_semanticModel, vbNode.SpanStart);

            if (csNode is InvocationExpressionSyntax invoke &&
                invoke.Expression is MemberAccessExpressionSyntax expr &&
                expr.Expression is IdentifierNameSyntax name && name.Identifier.ValueText == "Conversions" &&
                expr.Name.Identifier.ValueText == $"To{displayType}")
            {
                return(csNode);
            }

            var method = typeof(Microsoft.VisualBasic.CompilerServices.Conversions).GetMethod($"To{displayType}");

            if (method == null)
            {
                throw new NotImplementedException($"Unimplemented conversion for {displayType}");
            }

            // Need to use Conversions rather than Convert to match what VB does, eg. True -> -1
            _extraUsingDirectives.Add("Microsoft.VisualBasic.CompilerServices");
            var memberAccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                    SyntaxFactory.IdentifierName("Conversions"), SyntaxFactory.IdentifierName($"To{displayType}"));
            var arguments = SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(csNode)));

            return(SyntaxFactory.InvocationExpression(memberAccess, arguments));
        }
        private static void AnalyzeEqualsNotEquals(
            SyntaxNodeAnalysisContext context,
            BinaryExpressionSyntax binaryExpression,
            ExpressionSyntax left,
            ExpressionSyntax right,
            SyntaxKind kind,
            SyntaxKind kind2)
        {
            SyntaxKind leftKind = left.Kind();

            if (leftKind == kind)
            {
                switch (AnalyzeExpression(right, context.SemanticModel, context.CancellationToken))
                {
                case AnalysisResult.Boolean:
                {
                    SimplifyBooleanComparisonAnalysis.ReportDiagnostic(context, binaryExpression, left, right, fadeOut: true);
                    break;
                }

                case AnalysisResult.LogicalNotWithNullableBoolean:
                {
                    SimplifyBooleanComparisonAnalysis.ReportDiagnostic(context, binaryExpression, left, right, fadeOut: false);
                    break;
                }
                }
            }
            else if (leftKind == kind2)
            {
                switch (AnalyzeExpression(right, context.SemanticModel, context.CancellationToken))
                {
                case AnalysisResult.Boolean:
                {
                    RemoveRedundantBooleanLiteralAnalysis.ReportDiagnostic(context, binaryExpression, left, right);
                    break;
                }

                case AnalysisResult.LogicalNotWithNullableBoolean:
                {
                    SimplifyBooleanComparisonAnalysis.ReportDiagnostic(context, binaryExpression, left, right, fadeOut: false);
                    break;
                }
                }
            }
            else
            {
                SyntaxKind rightKind = right.Kind();

                if (rightKind == kind)
                {
                    switch (AnalyzeExpression(left, context.SemanticModel, context.CancellationToken))
                    {
                    case AnalysisResult.Boolean:
                    {
                        SimplifyBooleanComparisonAnalysis.ReportDiagnostic(context, binaryExpression, left, right, fadeOut: true);
                        break;
                    }

                    case AnalysisResult.LogicalNotWithNullableBoolean:
                    {
                        SimplifyBooleanComparisonAnalysis.ReportDiagnostic(context, binaryExpression, left, right, fadeOut: false);
                        break;
                    }
                    }
                }
                else if (rightKind == kind2)
                {
                    switch (AnalyzeExpression(left, context.SemanticModel, context.CancellationToken))
                    {
                    case AnalysisResult.Boolean:
                    {
                        RemoveRedundantBooleanLiteralAnalysis.ReportDiagnostic(context, binaryExpression, left, right);
                        break;
                    }

                    case AnalysisResult.LogicalNotWithNullableBoolean:
                    {
                        SimplifyBooleanComparisonAnalysis.ReportDiagnostic(context, binaryExpression, left, right, fadeOut: false);
                        break;
                    }
                    }
                }
            }
        }
        private static void CheckForBooleanConstant(BinaryExpressionSyntax binaryExpression, ExpressionSyntax booleanContantExpression,
                                                    ErrorLocation errorLocation, SyntaxNodeAnalysisContext context, bool leftSide)
        {
            var expression = leftSide
                ? binaryExpression.Left
                : binaryExpression.Right;

            if (!EquivalenceChecker.AreEquivalent(expression.RemoveParentheses(), booleanContantExpression))
            {
                return;
            }

            Location location;

            switch (errorLocation)
            {
            case ErrorLocation.Normal:
                location = expression.GetLocation();
                break;

            case ErrorLocation.Extended:
                location = CalculateExtendedLocation(binaryExpression, leftSide);
                break;

            case ErrorLocation.Inverted:
                location = CalculateExtendedLocation(binaryExpression, !leftSide);
                break;

            default:
                location = null;
                break;
            }

            context.ReportDiagnostic(Diagnostic.Create(rule, location));
        }
示例#48
0
        public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, bool addParenthesisIfNeeded = false, bool alwaysExplicit = false, bool implicitCastFromIntToEnum = false)
        {
            var conversionKind = AnalyzeConversion(vbNode, alwaysExplicit, implicitCastFromIntToEnum);

            csNode = addParenthesisIfNeeded && (conversionKind == TypeConversionKind.DestructiveCast || conversionKind == TypeConversionKind.NonDestructiveCast)
                ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode)
                : csNode;
            return(AddExplicitConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded));
        }
 private static void CheckForBooleanConstantOnLeftReportOnExtendedLocation(BinaryExpressionSyntax binaryExpression,
                                                                           ExpressionSyntax booleanContantExpression, SyntaxNodeAnalysisContext context)
 {
     CheckForBooleanConstant(binaryExpression, booleanContantExpression, ErrorLocation.Extended, context, leftSide: true);
 }
示例#50
0
        private (ExpressionSyntax fullInvocation, string identifierToken) PrepandCallToInvocation(IdentifierNameSyntax mockedObjectIdentifier, string prepandCall, ExpressionSyntax lambdaBody)
        {
            var prependInvocation = SyntaxFactory.InvocationExpression(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                                                            mockedObjectIdentifier, SyntaxFactory.IdentifierName(prepandCall)));
            var nameToken = lambdaBody.DescendantNodes().First(x => x.Kind() == mockedObjectIdentifier.Kind() && ((IdentifierNameSyntax)x).Identifier.ValueText == mockedObjectIdentifier.Identifier.ValueText);

            var fullInvocation = lambdaBody.ReplaceNode(nameToken, prependInvocation);

            return(fullInvocation, mockedObjectIdentifier.Identifier.ValueText);
        }
        public static void AnalyzeSimpleAssignmentExpression(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.SpanContainsDirectives())
            {
                return;
            }

            var assignment = (AssignmentExpressionSyntax)context.Node;

            if (assignment.IsParentKind(SyntaxKind.ObjectInitializerExpression))
            {
                return;
            }

            ExpressionSyntax left  = assignment.Left;
            ExpressionSyntax right = assignment.Right;

            if (left?.IsMissing != false)
            {
                return;
            }

            if (right?.IsKind(SyntaxKind.AddExpression, SyntaxKind.SubtractExpression) != true)
            {
                return;
            }

            var binaryExpression = (BinaryExpressionSyntax)right;

            ExpressionSyntax binaryLeft  = binaryExpression.Left;
            ExpressionSyntax binaryRight = binaryExpression.Right;

            if (binaryLeft?.IsMissing != false)
            {
                return;
            }

            if (binaryRight?.IsNumericLiteralExpression("1") != true)
            {
                return;
            }

            ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(left, context.CancellationToken);

            if (typeSymbol?.SupportsPrefixOrPostfixUnaryOperator() != true)
            {
                return;
            }

            if (!CSharpFactory.AreEquivalent(left, binaryLeft))
            {
                return;
            }

            string operatorText = GetOperatorText(assignment);

            ReportDiagnostic(context, assignment, operatorText);

            context.ReportToken(DiagnosticDescriptors.UsePostfixUnaryOperatorInsteadOfAssignmentFadeOut, assignment.OperatorToken, operatorText);
            context.ReportNode(DiagnosticDescriptors.UsePostfixUnaryOperatorInsteadOfAssignmentFadeOut, binaryLeft, operatorText);
            context.ReportNode(DiagnosticDescriptors.UsePostfixUnaryOperatorInsteadOfAssignmentFadeOut, binaryRight, operatorText);
        }
 private static void CheckForBooleanConstantOnRightReportOnNormalLocation(BinaryExpressionSyntax binaryExpression,
                                                                          ExpressionSyntax booleanContantExpression, SyntaxNodeAnalysisContext context)
 {
     CheckForBooleanConstant(binaryExpression, booleanContantExpression, ErrorLocation.Normal, context, leftSide: false);
 }
示例#53
0
 private static bool HasFloatingType(ExpressionSyntax right, ExpressionSyntax left, SemanticModel semanticModel)
 {
     return(IsExpressionFloatingType(right, semanticModel) ||
            IsExpressionFloatingType(left, semanticModel));
 }
        private static void Analyze(SyntaxNodeAnalysisContext context, SyntaxNode node, BlockSyntax body)
        {
            if (body == null)
            {
                return;
            }

            if (body.ContainsDiagnostics)
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = body.Statements;

            if (statements.Count != 2)
            {
                return;
            }

            if (!(statements[0] is IfStatementSyntax ifStatement))
            {
                return;
            }

            if (!(statements[1] is ReturnStatementSyntax returnStatement))
            {
                return;
            }

            ExpressionSyntax returnExpression = returnStatement.Expression;

            if (returnExpression?.IsKind(SyntaxKind.IdentifierName, SyntaxKind.SimpleMemberAccessExpression) != true)
            {
                return;
            }

            if (ifStatement.SpanOrTrailingTriviaContainsDirectives())
            {
                return;
            }

            if (returnStatement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            SimpleIfStatementInfo simpleIf = SyntaxInfo.SimpleIfStatementInfo(ifStatement);

            if (!simpleIf.Success)
            {
                return;
            }

            StatementSyntax statement = simpleIf.IfStatement.SingleNonBlockStatementOrDefault();

            if (statement == null)
            {
                return;
            }

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(statement);

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (!assignmentInfo.Left.IsKind(SyntaxKind.IdentifierName, SyntaxKind.SimpleMemberAccessExpression))
            {
                return;
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(simpleIf.Condition, semanticModel: semanticModel, allowedStyles: NullCheckStyles.CheckingNull, cancellationToken: cancellationToken);

            if (!nullCheck.Success)
            {
                return;
            }

            ExpressionSyntax expression = nullCheck.Expression;

            if (!expression.IsKind(SyntaxKind.IdentifierName, SyntaxKind.SimpleMemberAccessExpression))
            {
                return;
            }

            if (!(semanticModel.GetSymbol(expression, cancellationToken) is IFieldSymbol fieldSymbol))
            {
                return;
            }

            if (!ExpressionEquals(expression, assignmentInfo.Left))
            {
                return;
            }

            if (fieldSymbol.Type.IsNullableType() &&
                returnExpression.Kind() == SyntaxKind.SimpleMemberAccessExpression)
            {
                var memberAccessExpression = (MemberAccessExpressionSyntax)returnExpression;

                if (memberAccessExpression.Name is IdentifierNameSyntax identifierName &&
                    string.Equals(identifierName.Identifier.ValueText, "Value", StringComparison.Ordinal))
                {
                    returnExpression = memberAccessExpression.Expression;
                }
            }

            if (!ExpressionEquals(expression, returnExpression))
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context,
                                               DiagnosticDescriptors.SimplifyLazyInitialization,
                                               Location.Create(node.SyntaxTree, TextSpan.FromBounds(ifStatement.SpanStart, returnStatement.Span.End)));
        }
 internal ParenthesizedExpressionSyntax(SyntaxTree syntaxTree, SyntaxToken openParenthesisToken, ExpressionSyntax expression, SyntaxToken closeParenthesisToken)
     : base(syntaxTree)
 {
     OpenParenthesisToken  = openParenthesisToken;
     Expression            = expression;
     CloseParenthesisToken = closeParenthesisToken;
 }
示例#56
0
 private static bool IsExpressionFloatingType(ExpressionSyntax expression, SemanticModel semanticModel)
 {
     return(semanticModel.GetTypeInfo(expression).Type.IsAny(KnownType.FloatingPointNumbers));
 }
        private async Task ComputeCodeFixAsync(CodeFixContext context, Diagnostic diagnostic, ExpressionSyntax expression, SimpleNameSyntax simpleName)
        {
            switch (simpleName.Identifier.ValueText)
            {
            case "Count":
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                ComputeCodeFix(context, diagnostic, expression, simpleName, semanticModel, "Count", "Length");
                break;
            }

            case "Length":
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                ComputeCodeFix(context, diagnostic, expression, simpleName, semanticModel, "Length", "Count");
                break;
            }
            }
        }
示例#58
0
 private static BinaryExpressionSyntax TryGetBinaryExpression(ExpressionSyntax expression)
 {
     return(expression.RemoveParentheses() as BinaryExpressionSyntax);
 }
示例#59
0
        private BoundExpression BindExpression(ExpressionSyntax node)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            switch (node.Kind)
            {
            case SyntaxKind.TrueLiteralExpression:
            case SyntaxKind.FalseLiteralExpression:
            case SyntaxKind.NumericLiteralExpression:
                return(BindLiteralExpression((LiteralExpressionSyntax)node));

            case SyntaxKind.StringLiteralExpression:
                return(BindStringLiteralExpression((StringLiteralExpressionSyntax)node));

            case SyntaxKind.IdentifierName:
                return(BindIdentifierName((IdentifierNameSyntax)node));

            case SyntaxKind.QualifiedName:
                return(BindQualifiedName((QualifiedNameSyntax)node));

            case SyntaxKind.PreDecrementExpression:
            case SyntaxKind.PreIncrementExpression:
            case SyntaxKind.UnaryMinusExpression:
            case SyntaxKind.UnaryPlusExpression:
            case SyntaxKind.LogicalNotExpression:
            case SyntaxKind.BitwiseNotExpression:
                return(BindPrefixUnaryExpression((PrefixUnaryExpressionSyntax)node));

            case SyntaxKind.PostDecrementExpression:
            case SyntaxKind.PostIncrementExpression:
                return(BindPostfixUnaryExpression((PostfixUnaryExpressionSyntax)node));

            case SyntaxKind.AddExpression:
            case SyntaxKind.MultiplyExpression:
            case SyntaxKind.SubtractExpression:
            case SyntaxKind.DivideExpression:
            case SyntaxKind.ModuloExpression:
            case SyntaxKind.EqualsExpression:
            case SyntaxKind.NotEqualsExpression:
            case SyntaxKind.GreaterThanExpression:
            case SyntaxKind.LessThanExpression:
            case SyntaxKind.GreaterThanOrEqualExpression:
            case SyntaxKind.LessThanOrEqualExpression:
            case SyntaxKind.BitwiseAndExpression:
            case SyntaxKind.BitwiseOrExpression:
            case SyntaxKind.ExclusiveOrExpression:
            case SyntaxKind.LeftShiftExpression:
            case SyntaxKind.RightShiftExpression:
            case SyntaxKind.LogicalOrExpression:
            case SyntaxKind.LogicalAndExpression:
                return(BindBinaryExpression((BinaryExpressionSyntax)node));

            case SyntaxKind.FieldAccessExpression:
                return(BindFieldAccessExpression((FieldAccessExpressionSyntax)node));

            case SyntaxKind.FunctionInvocationExpression:
                return(BindFunctionInvocationExpression((FunctionInvocationExpressionSyntax)node));

            case SyntaxKind.MethodInvocationExpression:
                return(BindMethodInvocationExpression((MethodInvocationExpressionSyntax)node));

            case SyntaxKind.NumericConstructorInvocationExpression:
                return(BindNumericConstructorInvocationExpression((NumericConstructorInvocationExpressionSyntax)node));

            case SyntaxKind.SimpleAssignmentExpression:
            case SyntaxKind.AddAssignmentExpression:
            case SyntaxKind.SubtractAssignmentExpression:
            case SyntaxKind.MultiplyAssignmentExpression:
            case SyntaxKind.DivideAssignmentExpression:
            case SyntaxKind.ModuloAssignmentExpression:
            case SyntaxKind.AndAssignmentExpression:
            case SyntaxKind.ExclusiveOrAssignmentExpression:
            case SyntaxKind.OrAssignmentExpression:
            case SyntaxKind.LeftShiftAssignmentExpression:
            case SyntaxKind.RightShiftAssignmentExpression:
                return(BindAssignmentExpression((AssignmentExpressionSyntax)node));

            case SyntaxKind.CastExpression:
                return(BindCastExpression((CastExpressionSyntax)node));

            case SyntaxKind.CompoundExpression:
                return(BindCompoundExpression((CompoundExpressionSyntax)node));

            case SyntaxKind.ParenthesizedExpression:
                return(BindParenthesizedExpression((ParenthesizedExpressionSyntax)node));

            case SyntaxKind.ConditionalExpression:
                return(BindConditionalExpression((ConditionalExpressionSyntax)node));

            case SyntaxKind.ElementAccessExpression:
                return(BindElementAccessExpression((ElementAccessExpressionSyntax)node));

            case SyntaxKind.ArrayInitializerExpression:
                return(BindArrayInitializerExpression((ArrayInitializerExpressionSyntax)node));

            case SyntaxKind.CompileExpression:
                return(BindCompileExpression((CompileExpressionSyntax)node));

            default:
                throw new ArgumentOutOfRangeException(node.Kind.ToString());
            }
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsAnyCodeFixEnabled(
                    CodeFixIdentifiers.FixMemberAccessName,
                    CodeFixIdentifiers.RemoveAwaitKeyword))
            {
                return;
            }

            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out SyntaxNode node, predicate: f => f.IsKind(
                                                SyntaxKind.AwaitExpression,
                                                SyntaxKind.IdentifierName,
                                                SyntaxKind.GenericName,
                                                SyntaxKind.MemberBindingExpression)))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.TypeDoesNotContainDefinitionAndNoExtensionMethodCouldBeFound:
                {
                    switch (node)
                    {
                    case SimpleNameSyntax simpleName:
                    {
                        Debug.Assert(node.IsKind(SyntaxKind.IdentifierName, SyntaxKind.GenericName), node.Kind().ToString());

                        if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.FixMemberAccessName))
                        {
                            break;
                        }

                        if (!simpleName.IsParentKind(SyntaxKind.SimpleMemberAccessExpression))
                        {
                            break;
                        }

                        var memberAccess = (MemberAccessExpressionSyntax)simpleName.Parent;

                        if (memberAccess.IsParentKind(SyntaxKind.InvocationExpression))
                        {
                            break;
                        }

                        await ComputeCodeFixAsync(context, diagnostic, memberAccess.Expression, simpleName).ConfigureAwait(false);

                        break;
                    }

                    case MemberBindingExpressionSyntax memberBindingExpression:
                    {
                        if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.FixMemberAccessName))
                        {
                            break;
                        }

                        if (!(memberBindingExpression.Parent is ConditionalAccessExpressionSyntax conditionalAccessExpression))
                        {
                            break;
                        }

                        await ComputeCodeFixAsync(context, diagnostic, conditionalAccessExpression.Expression, memberBindingExpression.Name).ConfigureAwait(false);

                        break;
                    }

                    case AwaitExpressionSyntax awaitExpression:
                    {
                        if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveAwaitKeyword))
                        {
                            break;
                        }

                        CodeAction codeAction = CodeAction.Create(
                            "Remove 'await'",
                            cancellationToken =>
                                {
                                    ExpressionSyntax expression = awaitExpression.Expression;

                                    SyntaxTriviaList leadingTrivia = awaitExpression
                                                                     .GetLeadingTrivia()
                                                                     .AddRange(awaitExpression.AwaitKeyword.TrailingTrivia.EmptyIfWhitespace())
                                                                     .AddRange(expression.GetLeadingTrivia().EmptyIfWhitespace());

                                    ExpressionSyntax newNode = expression.WithLeadingTrivia(leadingTrivia);

                                    return(context.Document.ReplaceNodeAsync(awaitExpression, newNode, cancellationToken));
                                },
                            GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                        break;
                    }
                    }

                    break;
                }
                }
            }
        }