コード例 #1
0
        public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
        {
            // e.g. int x, y = 0;
            if (node.Declaration.Variables.Count > 1)
            {
                return node;
            }

            // e.g. int x;
            if (node.Declaration.Variables[0].Initializer == null)
            {
                return node;
            }

            VariableDeclaratorSyntax declarator = node.Declaration.Variables.First();
            TypeSyntax variableTypeName = node.Declaration.Type;
            TypeSymbol variableType = (TypeSymbol)semanticModel.GetSymbolInfo(variableTypeName).Symbol;

            TypeInfo initializerInfo = semanticModel.GetTypeInfo(declarator.Initializer.Value);

            // only when type is the same, (e.g. no base class casting)
            if (variableType == initializerInfo.Type)
            {
                TypeSyntax varTypeName = Syntax.IdentifierName("var")
                                     .WithLeadingTrivia(variableTypeName.GetLeadingTrivia())
                                     .WithTrailingTrivia(variableTypeName.GetTrailingTrivia());

                return node.ReplaceNode<LocalDeclarationStatementSyntax, TypeSyntax>(variableTypeName, varTypeName);
            }
            else
            {
                return node;
            }
        }
コード例 #2
0
ファイル: OverexposedLocal.cs プロジェクト: Strilanc/Croslyn
 public static IEnumerable<ReplaceAction> GetSimplifications(LocalDeclarationStatementSyntax declaration, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken))
 {
     var scope = declaration.Ancestors().OfType<BlockSyntax>().First();
     var i = scope.Statements.IndexOf(declaration);
     foreach (var v in declaration.Declaration.Variables) {
         if (v.Initializer != null) {
             if (v.Initializer.Value.HasSideEffects(model, assume) != false) continue;
             var anyEffects = declaration.Declaration.Variables.Where(e => e.Initializer != null && e.Initializer.Value.HasSideEffects(model, assume) != false).Any();
             if (v.Initializer.Value.IsConst(model) != true && anyEffects) continue;
         }
         var r = WithDeclarationMoved(scope, declaration, v, model, assume, cancellationToken);
         if (r == null) continue;
         var reducedDeclaration = declaration.Declaration.Variables.Count == 1
                                 ? new LocalDeclarationStatementSyntax[0]
                                 : new[] { declaration.WithDeclaration(declaration.Declaration.WithVariables(declaration.Declaration.Variables.Without(v))) };
         var newScopeWithReducedDeclaration = r.WithStatements(r.Statements.TakeSkipPutTake(i, 1, reducedDeclaration).List());
         yield return new ReplaceAction("Reduce scope", scope, newScopeWithReducedDeclaration, v.Identifier.Span);
     }
 }
コード例 #3
0
        public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
        {
            if (node.Declaration.Variables.Count > 1)
            {
                return node;
            }
            if (node.Declaration.Variables[0].Initializer == null)
            {
                return node;
            }

            VariableDeclaratorSyntax declarator = node.Declaration.Variables.First();
            TypeSyntax variableTypeName = node.Declaration.Type;

            TypeSymbol variableType =
                           (TypeSymbol)SemanticModel.GetSymbolInfo(variableTypeName)
                                                    .Symbol;

            TypeInfo initializerInfo =
                         SemanticModel.GetTypeInfo(declarator.Initializer.Value);

            if (variableType == initializerInfo.Type)
            {
                TypeSyntax varTypeName =
                               Syntax.IdentifierName("var")
                                     .WithLeadingTrivia(
                                          variableTypeName.GetLeadingTrivia())
                                     .WithTrailingTrivia(
                                          variableTypeName.GetTrailingTrivia());

                return node.ReplaceNode(variableTypeName, varTypeName);
            }
            else
            {
                return node;
            }
        }
 public override void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
 {
     // Here, we collect expression expressions from any/all initialization expressions
     AddVariableExpressions(node.Declaration.Variables, _expressions);
 }
コード例 #5
0
        public static ArgumentType ArgumentDefinedAs(FieldDeclarationSyntax fieldDeclaration, LocalDeclarationStatementSyntax localDeclarationStatement, ExpressionSyntax expression)
        {
            if (fieldDeclaration != null)
            {
                return(ArgumentType.Field);
            }

            if (localDeclarationStatement != null)
            {
                return(ArgumentType.Local);
            }

            if (expression != null)
            {
                return(ArgumentType.Expression);
            }

            return(ArgumentType.Unknown);
        }
コード例 #6
0
        public static Task <Document> RefactorAsync(Document document, IfAnalysis ifAnalysis, CancellationToken cancellationToken = default)
        {
            switch (ifAnalysis.Kind)
            {
            case IfAnalysisKind.IfElseToAssignmentWithCoalesceExpression:
            {
                return(IfElseToAssignmentWithCoalesceExpressionAsync(document, (IfElseToAssignmentWithCoalesceExpressionAnalysis)ifAnalysis, cancellationToken));
            }

            case IfAnalysisKind.IfElseToAssignmentWithConditionalExpression:
            {
                return(IfElseToAssignmentWithConditionalExpressionAsync(document, (IfElseToAssignmentWithConditionalExpressionAnalysis)ifAnalysis, cancellationToken));
            }

            case IfAnalysisKind.AssignmentAndIfToAssignmentWithConditionalExpression:
            {
                var analysis = (AssignmentAndIfToAssignmentWithConditionalExpressionAnalysis)ifAnalysis;

                ConditionalExpressionSyntax conditionalExpression = CreateConditionalExpression(analysis.IfStatement.Condition, analysis.WhenTrue, analysis.WhenFalse);

                ExpressionStatementSyntax newStatement = analysis.Statement.ReplaceNode(analysis.Right, conditionalExpression);

                return(ToAssignmentWithConditionalExpressionAsync(document, analysis, newStatement, cancellationToken));
            }

            case IfAnalysisKind.LocalDeclarationAndIfElseAssignmentWithConditionalExpression:
            {
                var analysis = (LocalDeclarationAndIfElseToAssignmentWithConditionalExpressionAnalysis)ifAnalysis;

                ConditionalExpressionSyntax conditionalExpression = CreateConditionalExpression(analysis.IfStatement.Condition, analysis.WhenTrue, analysis.WhenFalse);

                VariableDeclaratorSyntax declarator = analysis.Statement.Declaration.Variables[0];

                EqualsValueClauseSyntax initializer = declarator.Initializer;

                EqualsValueClauseSyntax newInitializer = (initializer != null)
                            ? initializer.WithValue(conditionalExpression)
                            : EqualsValueClause(conditionalExpression);

                LocalDeclarationStatementSyntax newStatement = analysis.Statement.ReplaceNode(declarator, declarator.WithInitializer(newInitializer));

                return(ToAssignmentWithConditionalExpressionAsync(document, analysis, newStatement, cancellationToken));
            }

            case IfAnalysisKind.IfElseToAssignmentWithExpression:
            {
                return(IfElseToAssignmentWithExpressionAsync(document, (IfElseToAssignmentWithExpressionAnalysis)ifAnalysis, cancellationToken));
            }

            case IfAnalysisKind.IfElseToAssignmentWithCondition:
            {
                return(IfElseToAssignmentWithConditionAsync(document, (IfElseToAssignmentWithConditionAnalysis)ifAnalysis, cancellationToken));
            }

            case IfAnalysisKind.IfElseToReturnWithCoalesceExpression:
            case IfAnalysisKind.IfElseToYieldReturnWithCoalesceExpression:
            case IfAnalysisKind.IfReturnToReturnWithCoalesceExpression:
            {
                return(IfToReturnWithCoalesceExpressionAsync(document, (IfToReturnWithCoalesceExpressionAnalysis)ifAnalysis, cancellationToken));
            }

            case IfAnalysisKind.IfElseToReturnWithConditionalExpression:
            {
                return(IfElseToReturnWithConditionalExpressionAsync(document, (IfElseToReturnWithConditionalExpressionAnalysis)ifAnalysis, cancellationToken));
            }

            case IfAnalysisKind.IfElseToReturnWithBooleanExpression:
            {
                return(IfElseToReturnWithBooleanExpressionAsync(document, (IfElseToReturnWithBooleanExpressionAnalysis)ifAnalysis, cancellationToken));
            }

            case IfAnalysisKind.IfElseToReturnWithExpression:
            case IfAnalysisKind.IfElseToYieldReturnWithExpression:
            case IfAnalysisKind.IfReturnToReturnWithExpression:
            {
                return(IfToReturnWithExpressionAsync(document, (IfToReturnWithExpressionAnalysis)ifAnalysis, cancellationToken));
            }

            case IfAnalysisKind.IfElseToYieldReturnWithConditionalExpression:
            {
                return(IfElseToYieldReturnWithConditionalExpressionAsync(document, (IfElseToYieldReturnWithConditionalExpressionAnalysis)ifAnalysis, cancellationToken));
            }

            case IfAnalysisKind.IfElseToYieldReturnWithBooleanExpression:
            {
                return(IfElseToYieldReturnWithBooleanExpressionAsync(document, (IfElseToYieldReturnWithBooleanExpressionAnalysis)ifAnalysis, cancellationToken));
            }

            case IfAnalysisKind.IfReturnToReturnWithConditionalExpression:
            {
                return(IfReturnToReturnWithConditionalExpressionAsync(document, (IfReturnToReturnWithConditionalExpressionAnalysis)ifAnalysis, cancellationToken));
            }

            case IfAnalysisKind.IfReturnToReturnWithBooleanExpression:
            {
                return(IfReturnToReturnWithBooleanExpressionAsync(document, (IfReturnToReturnWithBooleanExpressionAnalysis)ifAnalysis, cancellationToken));
            }

            default:
            {
                throw new InvalidOperationException();
            }
            }
        }
コード例 #7
0
        public bool TryGetPatternPieces(
            BinaryExpressionSyntax isExpression,
            out IfStatementSyntax ifStatement,
            out LocalDeclarationStatementSyntax localDeclarationStatement,
            out VariableDeclaratorSyntax declarator,
            out CastExpressionSyntax castExpression)
        {
            ifStatement = null;
            localDeclarationStatement = null;
            declarator     = null;
            castExpression = null;

            // The is check has to be in an if check: "if (x is Type)
            if (!isExpression.Parent.IsKind(SyntaxKind.IfStatement))
            {
                return(false);
            }

            ifStatement = (IfStatementSyntax)isExpression.Parent;
            if (!ifStatement.Statement.IsKind(SyntaxKind.Block))
            {
                return(false);
            }

            var ifBlock = (BlockSyntax)ifStatement.Statement;

            if (ifBlock.Statements.Count == 0)
            {
                return(false);
            }

            var firstStatement = ifBlock.Statements[0];

            if (!firstStatement.IsKind(SyntaxKind.LocalDeclarationStatement))
            {
                return(false);
            }

            localDeclarationStatement = (LocalDeclarationStatementSyntax)firstStatement;
            if (localDeclarationStatement.Declaration.Variables.Count != 1)
            {
                return(false);
            }

            declarator = localDeclarationStatement.Declaration.Variables[0];
            if (declarator.Initializer == null)
            {
                return(false);
            }

            var declaratorValue = declarator.Initializer.Value.WalkDownParentheses();

            if (!declaratorValue.IsKind(SyntaxKind.CastExpression))
            {
                return(false);
            }

            castExpression = (CastExpressionSyntax)declaratorValue;
            if (!SyntaxFactory.AreEquivalent(isExpression.Left.WalkDownParentheses(), castExpression.Expression.WalkDownParentheses(), topLevel: false) ||
                !SyntaxFactory.AreEquivalent(isExpression.Right.WalkDownParentheses(), castExpression.Type, topLevel: false))
            {
                return(false);
            }

            return(true);
        }
コード例 #8
0
        static bool DidVariableDeclarationTypeCorrespondToObviousCase(SyntaxNodeAnalysisContext nodeContext, LocalDeclarationStatementSyntax localVariable)
        {
            var singleVariable = localVariable.Declaration.Variables.First();
            var initializer    = singleVariable.Initializer;

            if (initializer == null)
            {
                return(false);
            }
            var initializerExpression = initializer.Value;

            var variableTypeName = localVariable.Declaration.Type;
            var semanticModel    = nodeContext.SemanticModel;
            var variableType     = semanticModel.GetSymbolInfo(variableTypeName, nodeContext.CancellationToken).Symbol as ITypeSymbol;

            return(IsArrayTypeSomeObviousTypeCase(nodeContext, initializerExpression, variableType, localVariable) ||
                   IsObjectCreationSomeObviousTypeCase(nodeContext, initializerExpression, variableType) ||
                   IsCastingSomeObviousTypeCase(nodeContext, initializerExpression, variableType) /*||
                                                                                                   * IsPropertyAccessSomeObviousTypeCase(nodeContext, initializerExpression, variableType)*/);
        }
コード例 #9
0
ファイル: CodeAction.cs プロジェクト: piotrosz/RoslynChart
 public CodeAction(IDocument document, LocalDeclarationStatementSyntax localDeclaration)
 {
     this.document = document;
     this.localDeclaration = localDeclaration;
 }
コード例 #10
0
            private static SyntaxToken ApplyTriviaFromDeclarationToAssignmentIdentifier(LocalDeclarationStatementSyntax declarationStatement, bool firstVariableToAttachTrivia, VariableDeclaratorSyntax variable)
            {
                var identifier = variable.Identifier;
                var typeSyntax = declarationStatement.Declaration.Type;

                if (firstVariableToAttachTrivia && typeSyntax != null)
                {
                    var identifierLeadingTrivia = new SyntaxTriviaList();

                    if (typeSyntax.HasLeadingTrivia)
                    {
                        identifierLeadingTrivia = identifierLeadingTrivia.AddRange(typeSyntax.GetLeadingTrivia());
                    }

                    identifierLeadingTrivia = identifierLeadingTrivia.AddRange(identifier.LeadingTrivia);
                    identifier = identifier.WithLeadingTrivia(identifierLeadingTrivia);
                }

                return(identifier);
            }
コード例 #11
0
        public void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
        {
            if (node == null)
                throw new ArgumentNullException("node");

            node.Validate();

            WriteLeadingTrivia(node);

            _writer.WriteIndent();

            if ((node.Modifiers & Modifiers.Const) != 0)
            {
                _writer.WriteKeyword(PrinterKeyword.Const);
                _writer.WriteSpace();
            }

            node.Declaration.Accept(this);

            _writer.EndStatement();

            WriteTrailingTrivia(node);
        }
コード例 #12
0
ファイル: Function.cs プロジェクト: VendanAndrews/ls2csc
        public void Flatten(LocalDeclarationStatementSyntax node, List<FlatStatement> instructions)
        {
            TypeInfo ti = Model.GetTypeInfo(node.Declaration.Type);

            foreach (VariableDeclaratorSyntax vds in node.Declaration.Variables)
            {
                Flatten(ti.Type, vds, instructions);
            }
        }
コード例 #13
0
ファイル: OverexposedLocal.cs プロジェクト: Strilanc/Croslyn
        private static BlockSyntax WithDeclarationMoved(BlockSyntax scope, LocalDeclarationStatementSyntax declaration, VariableDeclaratorSyntax v, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken)
        {
            Func<SyntaxNode, bool> accesses = s => s.DescendantNodes()
                                                    .OfType<IdentifierNameSyntax>()
                                                    .Where(e => e.Identifier.ValueText == v.Identifier.ValueText)
                                                    .Where(e => model.GetSymbolInfo(e).Symbol == model.GetDeclaredSymbol(v))
                                                    .Any();

            var isOutermostScope = scope.Statements.Contains(declaration);
            var scopeStatements = isOutermostScope
                                ? scope.Statements.SkipWhile(e => e != declaration).Skip(1).ToArray()
                                : scope.Statements.ToArray();

            var statementAccesses = scope.Statements.Where(s => accesses(s)).ToArray();
            if (statementAccesses.Length == 0) return null; //unused local, no change
            var firstAccess = statementAccesses.FirstOrDefault();
            var insertBeforeTarget = firstAccess;
            if (v.Initializer != null && v.Initializer.Value.IsConst(model) != true) {
                insertBeforeTarget = scopeStatements
                                    .TakeWhile(e => e != firstAccess)
                                    .SkipWhile(e => e.HasSideEffects(model, assume) == false)
                                    .Append(firstAccess)
                                    .FirstOrDefault();
            }

            if (statementAccesses.Length == 1 && insertBeforeTarget == firstAccess) {
                if (firstAccess is BlockSyntax) {
                    var reducedScope = WithDeclarationMoved((BlockSyntax)firstAccess, declaration, v, model, assume, cancellationToken);
                    return scope.WithStatements(scope.Statements.Replace(firstAccess, reducedScope));
                }
                if (firstAccess is IfStatementSyntax) {
                    var s = (IfStatementSyntax)firstAccess;
                    if (!accesses(s.Condition)) {
                        if (!accesses(s.Statement) && s.Else.Statement is BlockSyntax) {
                            return scope.WithStatements(
                                scope.Statements.Replace(
                                    s,
                                    s.WithElse(
                                        s.Else.WithStatement(
                                            WithDeclarationMoved(
                                                (BlockSyntax)s.Else.Statement,
                                                declaration,
                                                v,
                                                model,
                                                assume,
                                                cancellationToken)))));
                        } else if (s.Statement is BlockSyntax && (s.Else == null || !accesses(s.Else.Statement))) {
                            return scope.WithStatements(
                                scope.Statements.Replace(
                                    s,
                                    s.WithStatement(
                                        WithDeclarationMoved(
                                            (BlockSyntax)s.Statement,
                                            declaration,
                                            v,
                                            model,
                                            assume,
                                            cancellationToken))));
                        }
                    }
                }
            }
            if (isOutermostScope && scopeStatements.TakeWhile(e => e != insertBeforeTarget).Where(e => !(e is LocalDeclarationStatementSyntax)).None())
                return null; //minimal scope already

            var newDeclaration = declaration.WithDeclaration(declaration.Declaration.WithVariables(v.SepList1()));
            return scope.WithStatements(scope.Statements.InsertBefore(insertBeforeTarget, newDeclaration).List());
        }
コード例 #14
0
        private Method TraverseVarDecls(LocalDeclarationStatementSyntax ldss)
        {
            Method retMethod = new Method();
            List<Encapsulation> accessability = new List<Encapsulation>();
            List<Qualifiers> qualifiers = new List<Qualifiers>();
            foreach (SyntaxToken st in ldss.Modifiers)
            {
                string modifier = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(st.ValueText);
                Encapsulation encap;
                Qualifiers qual;
                if (System.Enum.TryParse<Encapsulation>(modifier, out encap))
                {
                    accessability.Add(encap);
                }
                else if (System.Enum.TryParse<Qualifiers>(modifier, out qual))
                {
                    qualifiers.Add(qual);
                }
            }

            foreach (SyntaxNode ss in ldss.ChildNodes())
            {
                if (ss is VariableDeclaratorSyntax)
                {
                    Variables retVar = new Variables();
                    retVar = TraverseVariableSyntax(ss as VariableDeclaratorSyntax, accessability, qualifiers);
                    retMethod.AccessedVariables.Add(retVar);
                }
                else if (ss is CallStatementSyntax)
                {
                    retMethod.InvokedMethods.Add(TraverseInvokedMethod(ss as CallStatementSyntax));
                }
            }

            return retMethod;
        }
コード例 #15
0
 public override void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
 {
     _currentBlock.Nodes.Add(node);
 }
コード例 #16
0
        private async Task <Document> MakeConstAsync(Document document, LocalDeclarationStatementSyntax localDeclaration, CancellationToken cancellationToken)
        {
            // Remove the leading trivia from the local declaration.
            var firstToken    = localDeclaration.GetFirstToken();
            var leadingTrivia = firstToken.LeadingTrivia;
            var trimmedLocal  = localDeclaration.ReplaceToken(
                firstToken, firstToken.WithLeadingTrivia(SyntaxTriviaList.Empty));

            // Create a const token with the leading trivia.
            var constToken = SyntaxFactory.Token(leadingTrivia, SyntaxKind.ConstKeyword, SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker));

            // Insert the const token into the modifiers list, creating a new modifiers list.
            var newModifiers = trimmedLocal.Modifiers.Insert(0, constToken);

            // If the type of declaration is 'var', create a new type name for the
            // type inferred for 'var'.
            var variableDeclaration = localDeclaration.Declaration;
            var variableTypeName    = variableDeclaration.Type;

            if (variableTypeName.IsVar)
            {
                var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

                // Special case: Ensure that 'var' isn't actually an alias to another type
                // (e.g. using var = System.String).
                var aliasInfo = semanticModel.GetAliasInfo(variableTypeName);
                if (aliasInfo == null)
                {
                    // Retrieve the type inferred for var.
                    var type = semanticModel.GetTypeInfo(variableTypeName).ConvertedType;

                    // Special case: Ensure that 'var' isn't actually a type named 'var'.
                    if (type.Name != "var")
                    {
                        // Create a new TypeSyntax for the inferred type. Be careful
                        // to keep any leading and trailing trivia from the var keyword.
                        var typeName = SyntaxFactory.ParseTypeName(type.ToDisplayString())
                                       .WithLeadingTrivia(variableTypeName.GetLeadingTrivia())
                                       .WithTrailingTrivia(variableTypeName.GetTrailingTrivia());

                        // Add an annotation to simplify the type name.
                        var simplifiedTypeName = typeName.WithAdditionalAnnotations(Simplifier.Annotation);

                        // Replace the type in the variable declaration.
                        variableDeclaration = variableDeclaration.WithType(simplifiedTypeName);
                    }
                }
            }

            // Produce the new local declaration.
            var newLocal = trimmedLocal.WithModifiers(newModifiers)
                           .WithDeclaration(variableDeclaration);

            // Add an annotation to format the new local declaration.
            var formattedLocal = newLocal.WithAdditionalAnnotations(Formatter.Annotation);

            // Replace the old local declaration with the new local declaration.
            var root = await document.GetSyntaxRootAsync(cancellationToken);

            var newRoot = root.ReplaceNode(localDeclaration, formattedLocal);

            // Return document with transformed tree.
            return(document.WithSyntaxRoot(newRoot));
        }
コード例 #17
0
        internal static async Task ComputeRefactoringAsync(RefactoringContext context, LocalDeclarationStatementSyntax localDeclaration)
        {
            ConditionalExpressionSyntax conditionalExpression = GetConditionalExpression(localDeclaration);

            if (conditionalExpression != null)
            {
                await ComputeRefactoringAsync(context, localDeclaration, conditionalExpression).ConfigureAwait(false);
            }
        }
コード例 #18
0
ファイル: Analyzer.cs プロジェクト: legigor/Nake
 public override void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
 {
     visitingConstant = node.Modifiers.Any(SyntaxKind.ConstKeyword);
     base.VisitLocalDeclarationStatement(node);
     visitingConstant = false;
 }
コード例 #19
0
        private static async Task ComputeRefactoringAsync(RefactoringContext context, LocalDeclarationStatementSyntax localDeclaration, ConditionalExpressionSyntax conditionalExpression)
        {
            if (localDeclaration?.IsParentKind(SyntaxKind.Block, SyntaxKind.SwitchSection) == true)
            {
                TypeSyntax type = localDeclaration.Declaration.Type;

                if (type != null)
                {
                    bool success = true;

                    if (type.IsVar)
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken);

                        success = typeSymbol?.SupportsExplicitDeclaration() == true;
                    }

                    if (success)
                    {
                        context.RegisterRefactoring(
                            "Replace ?: with if-else",
                            cancellationToken => RefactorAsync(context.Document, localDeclaration, conditionalExpression, cancellationToken));
                    }
                }
            }
        }
コード例 #20
0
        static bool IsArrayTypeSomeObviousTypeCase(SyntaxNodeAnalysisContext nodeContext, ExpressionSyntax initializerExpression, ITypeSymbol variableType, LocalDeclarationStatementSyntax localVariable)
        {
            var arrayCreationExpressionSyntax = initializerExpression as ArrayCreationExpressionSyntax;

            if (arrayCreationExpressionSyntax != null)
            {
                if (arrayCreationExpressionSyntax.Type.IsMissing)
                {
                    return(false);
                }

                var arrayType = nodeContext.SemanticModel.GetTypeInfo(arrayCreationExpressionSyntax).ConvertedType;
                return(arrayType != null && arrayCreationExpressionSyntax.Initializer != null && variableType.Equals(arrayType));
            }

            return(false);
        }
コード例 #21
0
 public override BoundNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
 {
     return(new BoundLocalDeclarationStatement(node, (BoundVariableDeclarationStatement)VisitVariableDeclaration(node.Declaration)));
 }
コード例 #22
0
 /// <summary>
 /// Unwrap
 /// </summary>
 /// <param name="declaration"></param>
 /// <param name="state"></param>
 /// <returns></returns>
 private VariableState VisitLocalDeclaration(LocalDeclarationStatementSyntax declaration, ExecutionState state)
 {
     return(VisitVariableDeclaration(declaration.Declaration, state));
 }
コード例 #23
0
        public static async Task ComputeRefactoringAsync(RefactoringContext context, ConditionalExpressionSyntax conditionalExpression)
        {
            ExpressionSyntax expression = conditionalExpression.WalkUpParentheses();

            SyntaxNode parent = expression.Parent;

            if (parent.IsKind(SyntaxKind.ReturnStatement, SyntaxKind.YieldReturnStatement))
            {
                var statement = (StatementSyntax)parent;

                RegisterRefactoring(context, conditionalExpression, statement);

                if (IsRecursive())
                {
                    RegisterRefactoring(context, conditionalExpression, statement, recursive: true);
                }
            }
            else if (parent is AssignmentExpressionSyntax assignment)
            {
                if (assignment.Parent is ExpressionStatementSyntax expressionStatement)
                {
                    RegisterRefactoring(context, conditionalExpression, expressionStatement);

                    if (IsRecursive())
                    {
                        RegisterRefactoring(context, conditionalExpression, expressionStatement, recursive: true);
                    }
                }
            }
            else
            {
                SingleLocalDeclarationStatementInfo localDeclarationInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(expression);

                if (localDeclarationInfo.Success)
                {
                    TypeSyntax type = localDeclarationInfo.Type;

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    if (!type.IsVar ||
                        semanticModel.GetTypeSymbol(type, context.CancellationToken)?.SupportsExplicitDeclaration() == true)
                    {
                        LocalDeclarationStatementSyntax statement = localDeclarationInfo.Statement;

                        RegisterRefactoring(context, conditionalExpression, statement, semanticModel);

                        if (IsRecursive())
                        {
                            RegisterRefactoring(context, conditionalExpression, statement, semanticModel, recursive: true);
                        }
                    }
                }
            }

            bool IsRecursive()
            {
                return(conditionalExpression
                       .WhenFalse
                       .WalkDownParentheses()
                       .IsKind(SyntaxKind.ConditionalExpression));
            }
        }
コード例 #24
0
 public virtual string GetOrDeclareComponentArray(RoslynEcsTranslator.IterationContext ctx, string componentTypeName, out LocalDeclarationStatementSyntax arrayInitialization, out StatementSyntax arrayDisposal)
 {
     return(Parent.GetOrDeclareComponentArray(ctx, componentTypeName, out arrayInitialization, out arrayDisposal));
 }
コード例 #25
0
 private LocalDeclarationStatementInfo(LocalDeclarationStatementSyntax statement)
 {
     Statement = statement;
 }
コード例 #26
0
        private Document RewriteExpressionBodiedMemberAndIntroduceLocalDeclaration(
            SemanticDocument document,
            ArrowExpressionClauseSyntax arrowExpression,
            ExpressionSyntax expression,
            NameSyntax newLocalName,
            LocalDeclarationStatementSyntax declarationStatement,
            bool allOccurrences,
            CancellationToken cancellationToken)
        {
            var oldBody          = arrowExpression;
            var oldParentingNode = oldBody.Parent;
            var leadingTrivia    = oldBody.GetLeadingTrivia()
                                   .AddRange(oldBody.ArrowToken.TrailingTrivia);

            var newStatement = Rewrite(document, expression, newLocalName, document, oldBody.Expression, allOccurrences, cancellationToken);
            var newBody      = SyntaxFactory.Block(declarationStatement, SyntaxFactory.ReturnStatement(newStatement))
                               .WithLeadingTrivia(leadingTrivia)
                               .WithTrailingTrivia(oldBody.GetTrailingTrivia())
                               .WithAdditionalAnnotations(Formatter.Annotation);

            SyntaxNode newParentingNode = null;

            if (oldParentingNode is BasePropertyDeclarationSyntax baseProperty)
            {
                var getAccessor  = SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration, newBody);
                var accessorList = SyntaxFactory.AccessorList(SyntaxFactory.List(new[] { getAccessor }));

                newParentingNode = baseProperty.RemoveNode(oldBody, SyntaxRemoveOptions.KeepNoTrivia);

                if (newParentingNode.IsKind(SyntaxKind.PropertyDeclaration))
                {
                    var propertyDeclaration = ((PropertyDeclarationSyntax)newParentingNode);
                    newParentingNode = propertyDeclaration
                                       .WithAccessorList(accessorList)
                                       .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))
                                       .WithTrailingTrivia(propertyDeclaration.SemicolonToken.TrailingTrivia);
                }
                else if (newParentingNode.IsKind(SyntaxKind.IndexerDeclaration))
                {
                    var indexerDeclaration = ((IndexerDeclarationSyntax)newParentingNode);
                    newParentingNode = indexerDeclaration
                                       .WithAccessorList(accessorList)
                                       .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))
                                       .WithTrailingTrivia(indexerDeclaration.SemicolonToken.TrailingTrivia);
                }
            }
            else if (oldParentingNode is BaseMethodDeclarationSyntax baseMethod)
            {
                newParentingNode = baseMethod.RemoveNode(oldBody, SyntaxRemoveOptions.KeepNoTrivia)
                                   .WithBody(newBody);

                if (newParentingNode.IsKind(SyntaxKind.MethodDeclaration))
                {
                    var methodDeclaration = ((MethodDeclarationSyntax)newParentingNode);
                    newParentingNode = methodDeclaration
                                       .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))
                                       .WithTrailingTrivia(methodDeclaration.SemicolonToken.TrailingTrivia);
                }
                else if (newParentingNode.IsKind(SyntaxKind.OperatorDeclaration))
                {
                    var operatorDeclaration = ((OperatorDeclarationSyntax)newParentingNode);
                    newParentingNode = operatorDeclaration
                                       .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))
                                       .WithTrailingTrivia(operatorDeclaration.SemicolonToken.TrailingTrivia);
                }
                else if (newParentingNode.IsKind(SyntaxKind.ConversionOperatorDeclaration))
                {
                    var conversionOperatorDeclaration = ((ConversionOperatorDeclarationSyntax)newParentingNode);
                    newParentingNode = conversionOperatorDeclaration
                                       .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))
                                       .WithTrailingTrivia(conversionOperatorDeclaration.SemicolonToken.TrailingTrivia);
                }
            }

            var newRoot = document.Root.ReplaceNode(oldParentingNode, newParentingNode);

            return(document.Document.WithSyntaxRoot(newRoot));
        }
コード例 #27
0
        private static ImmutableArray <IfRefactoring> Analyze(
            LocalDeclarationStatementSyntax localDeclarationStatement,
            IfStatementSyntax ifStatement,
            IfAnalysisOptions options)
        {
            VariableDeclaratorSyntax declarator = localDeclarationStatement
                                                  .Declaration?
                                                  .Variables
                                                  .SingleOrDefault(shouldthrow: false);

            if (declarator == null)
            {
                return(Empty);
            }

            ElseClauseSyntax elseClause = ifStatement.Else;

            if (elseClause?.Statement?.IsKind(SyntaxKind.IfStatement) != false)
            {
                return(Empty);
            }

            SimpleAssignmentStatementInfo assignment1 = SyntaxInfo.SimpleAssignmentStatementInfo(ifStatement.GetSingleStatementOrDefault());

            if (!assignment1.Success)
            {
                return(Empty);
            }

            SimpleAssignmentStatementInfo assignment2 = SyntaxInfo.SimpleAssignmentStatementInfo(elseClause.GetSingleStatementOrDefault());

            if (!assignment2.Success)
            {
                return(Empty);
            }

            if (!assignment1.Left.IsKind(SyntaxKind.IdentifierName))
            {
                return(Empty);
            }

            if (!assignment2.Left.IsKind(SyntaxKind.IdentifierName))
            {
                return(Empty);
            }

            string identifier1 = ((IdentifierNameSyntax)assignment1.Left).Identifier.ValueText;
            string identifier2 = ((IdentifierNameSyntax)assignment2.Left).Identifier.ValueText;

            if (!string.Equals(identifier1, identifier2, StringComparison.Ordinal))
            {
                return(Empty);
            }

            if (!string.Equals(identifier1, declarator.Identifier.ValueText, StringComparison.Ordinal))
            {
                return(Empty);
            }

            if (!options.CheckSpanDirectives(ifStatement.Parent, TextSpan.FromBounds(localDeclarationStatement.SpanStart, ifStatement.Span.End)))
            {
                return(Empty);
            }

            return(new LocalDeclarationAndIfElseAssignmentWithConditionalExpression(localDeclarationStatement, ifStatement, assignment1.Right, assignment2.Right).ToImmutableArray());
        }
        private async Task <Document> IntroduceLocalDeclarationIntoBlockAsync(
            SemanticDocument document,
            BlockSyntax block,
            ExpressionSyntax expression,
            NameSyntax newLocalName,
            LocalDeclarationStatementSyntax declarationStatement,
            bool allOccurrences,
            CancellationToken cancellationToken)
        {
            declarationStatement = declarationStatement.WithAdditionalAnnotations(Formatter.Annotation);

            SyntaxNode scope = block;

            // If we're within a non-static local function, our scope for the new local declaration is expanded to include the enclosing member.
            var localFunction = block.GetAncestor <LocalFunctionStatementSyntax>();

            if (localFunction != null && !localFunction.Modifiers.Any(modifier => modifier.IsKind(SyntaxKind.StaticKeyword)))
            {
                scope = block.GetAncestor <MemberDeclarationSyntax>();
            }

            var matches = FindMatches(document, expression, document, scope, allOccurrences, cancellationToken);

            Debug.Assert(matches.Contains(expression));

            (document, matches) = await ComplexifyParentingStatementsAsync(document, matches, cancellationToken).ConfigureAwait(false);

            // Our original expression should have been one of the matches, which were tracked as part
            // of complexification, so we can retrieve the latest version of the expression here.
            expression = document.Root.GetCurrentNode(expression);

            var root = document.Root;
            ISet <StatementSyntax> allAffectedStatements = new HashSet <StatementSyntax>(matches.SelectMany(expr => GetApplicableStatementAncestors(expr)));

            SyntaxNode innermostCommonBlock;

            var innermostStatements = new HashSet <StatementSyntax>(matches.Select(expr => GetApplicableStatementAncestors(expr).First()));

            if (innermostStatements.Count == 1)
            {
                // if there was only one match, or all the matches came from the same statement
                var statement = innermostStatements.Single();

                // and the statement is an embedded statement without a block, we want to generate one
                // around this statement rather than continue going up to find an actual block
                if (!IsBlockLike(statement.Parent))
                {
                    root = root.TrackNodes(allAffectedStatements.Concat(new SyntaxNode[] { expression, statement }));
                    root = root.ReplaceNode(root.GetCurrentNode(statement),
                                            SyntaxFactory.Block(root.GetCurrentNode(statement)).WithAdditionalAnnotations(Formatter.Annotation));

                    expression            = root.GetCurrentNode(expression);
                    allAffectedStatements = allAffectedStatements.Select(root.GetCurrentNode).ToSet();

                    statement = root.GetCurrentNode(statement);
                }

                innermostCommonBlock = statement.Parent;
            }
            else
            {
                innermostCommonBlock = innermostStatements.FindInnermostCommonNode(IsBlockLike);
            }

            var firstStatementAffectedIndex = GetFirstStatementAffectedIndex(innermostCommonBlock, matches, GetStatements(innermostCommonBlock).IndexOf(allAffectedStatements.Contains));

            var newInnerMostBlock = Rewrite(
                document, expression, newLocalName, document, innermostCommonBlock, allOccurrences, cancellationToken);

            var statements          = InsertWithinTriviaOfNext(GetStatements(newInnerMostBlock), declarationStatement, firstStatementAffectedIndex);
            var finalInnerMostBlock = WithStatements(newInnerMostBlock, statements);

            var newRoot = root.ReplaceNode(innermostCommonBlock, finalInnerMostBlock);

            return(document.Document.WithSyntaxRoot(newRoot));
        }
 public static SyntaxToken UsingKeyword(this LocalDeclarationStatementSyntax syntax)
 {
     return(UsingKeywordAccessor(syntax));
 }
コード例 #30
0
ファイル: CsToLua_Misc.cs プロジェクト: winslylord/Cs2Lua
 public override void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
 {
     base.VisitLocalDeclarationStatement(node);
 }
 public static LocalDeclarationStatementSyntax WithAwaitKeyword(this LocalDeclarationStatementSyntax syntax, SyntaxToken awaitKeyword)
 {
     return(WithAwaitKeywordAccessor(syntax, awaitKeyword));
 }
コード例 #32
0
        protected IEnumerable <StatementSyntax> GenerateConditionalAllocationSyntax(
            TypePositionInfo info,
            StubCodeContext context,
            int stackallocMaxSize)
        {
            (_, string nativeIdentifier) = context.GetIdentifiers(info);

            string allocationMarkerIdentifier = GetAllocationMarkerIdentifier(info, context);
            string byteLenIdentifier          = GetByteLengthIdentifier(info, context);
            string stackAllocPtrIdentifier    = GetStackAllocIdentifier(info, context);
            // <native> = <allocationExpression>;
            ExpressionStatementSyntax allocationStatement = ExpressionStatement(
                AssignmentExpression(
                    SyntaxKind.SimpleAssignmentExpression,
                    IdentifierName(nativeIdentifier),
                    GenerateAllocationExpression(info, context, Identifier(byteLenIdentifier), out bool allocationRequiresByteLength)));

            // int <byteLenIdentifier> = <byteLengthExpression>;
            LocalDeclarationStatementSyntax byteLenAssignment = LocalDeclarationStatement(
                VariableDeclaration(
                    PredefinedType(Token(SyntaxKind.IntKeyword)),
                    SingletonSeparatedList(
                        VariableDeclarator(byteLenIdentifier)
                        .WithInitializer(EqualsValueClause(
                                             GenerateByteLengthCalculationExpression(info, context))))));

            if (!UsesConditionalStackAlloc(info, context))
            {
                List <StatementSyntax> statements = new List <StatementSyntax>();
                if (allocationRequiresByteLength)
                {
                    statements.Add(byteLenAssignment);
                }
                statements.Add(allocationStatement);
                yield return(ExpressionStatement(AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
                                                                      IdentifierName(nativeIdentifier),
                                                                      LiteralExpression(SyntaxKind.NullLiteralExpression))));

                yield return(IfStatement(
                                 GenerateNullCheckExpression(info, context),
                                 Block(statements)));

                yield break;
            }

            // Code block for stackalloc if number of bytes is below threshold size
            BlockSyntax marshalOnStack = Block(
                // byte* <stackAllocPtr> = stackalloc byte[<byteLen>];
                LocalDeclarationStatement(
                    VariableDeclaration(
                        PointerType(PredefinedType(Token(SyntaxKind.ByteKeyword))),
                        SingletonSeparatedList(
                            VariableDeclarator(stackAllocPtrIdentifier)
                            .WithInitializer(EqualsValueClause(
                                                 StackAllocArrayCreationExpression(
                                                     ArrayType(
                                                         PredefinedType(Token(SyntaxKind.ByteKeyword)),
                                                         SingletonList(
                                                             ArrayRankSpecifier(SingletonSeparatedList <ExpressionSyntax>(
                                                                                    IdentifierName(byteLenIdentifier))))))))))),
                GenerateStackallocOnlyValueMarshalling(info, context, Identifier(byteLenIdentifier), Identifier(stackAllocPtrIdentifier)),
                // <nativeIdentifier> = <stackAllocPtr>;
                ExpressionStatement(
                    AssignmentExpression(
                        SyntaxKind.SimpleAssignmentExpression,
                        IdentifierName(nativeIdentifier),
                        CastExpression(
                            AsNativeType(info),
                            IdentifierName(stackAllocPtrIdentifier)))));

            //   if (<byteLen> > <StackAllocBytesThreshold>)
            //   {
            //       <allocationStatement>;
            //       <allocationMarker> = true;
            //   }
            //   else
            //   {
            //       byte* <stackAllocPtr> = stackalloc byte[<byteLen>];
            //       <marshalValueOnStackStatement>;
            //       <native> = (<nativeType>)<stackAllocPtr>;
            //   }
            IfStatementSyntax allocBlock = IfStatement(
                BinaryExpression(
                    SyntaxKind.GreaterThanExpression,
                    IdentifierName(byteLenIdentifier),
                    LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(stackallocMaxSize))),
                Block(
                    allocationStatement,
                    ExpressionStatement(
                        AssignmentExpression(
                            SyntaxKind.SimpleAssignmentExpression,
                            IdentifierName(allocationMarkerIdentifier),
                            LiteralExpression(SyntaxKind.TrueLiteralExpression)))),
                ElseClause(marshalOnStack));

            yield return(IfStatement(
                             GenerateNullCheckExpression(info, context),
                             Block(byteLenAssignment, allocBlock)));
        }
 public static LocalDeclarationStatementSyntax WithUsingKeyword(this LocalDeclarationStatementSyntax syntax, SyntaxToken usingKeyword)
 {
     return(WithUsingKeywordAccessor(syntax, usingKeyword));
 }
コード例 #34
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddComparisonWithBooleanLiteral) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.CreateSingletonArray) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseUncheckedExpression) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConstModifier) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseCoalesceExpression) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConditionThatIsAlwaysEqualToTrueOrFalse))
            {
                return;
            }

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

            if (!TryFindNode(root, context.Span, out ExpressionSyntax expression))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.CannotImplicitlyConvertTypeExplicitConversionExists:
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    TypeInfo typeInfo = semanticModel.GetTypeInfo(expression, context.CancellationToken);

                    ITypeSymbol type          = typeInfo.Type;
                    ITypeSymbol convertedType = typeInfo.ConvertedType;

                    if (type?.IsNamedType() == true)
                    {
                        var namedType = (INamedTypeSymbol)type;

                        if (namedType.ConstructedFrom.SpecialType == SpecialType.System_Nullable_T)
                        {
                            if (convertedType?.IsBoolean() == true ||
                                AddComparisonWithBooleanLiteralRefactoring.IsCondition(expression))
                            {
                                if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddComparisonWithBooleanLiteral))
                                {
                                    CodeAction codeAction = CodeAction.Create(
                                        AddComparisonWithBooleanLiteralRefactoring.GetTitle(expression),
                                        cancellationToken => AddComparisonWithBooleanLiteralRefactoring.RefactorAsync(context.Document, expression, cancellationToken),
                                        GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddComparisonWithBooleanLiteral));

                                    context.RegisterCodeFix(codeAction, diagnostic);
                                }
                            }
                            else if (namedType.TypeArguments[0].Equals(convertedType))
                            {
                                if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseCoalesceExpression))
                                {
                                    CodeAction codeAction = CodeAction.Create(
                                        "Use coalesce expression",
                                        cancellationToken =>
                                        {
                                            ExpressionSyntax defaultValue = convertedType.ToDefaultValueSyntax(semanticModel, expression.SpanStart);

                                            ExpressionSyntax newNode = CoalesceExpression(expression.WithoutTrivia(), defaultValue)
                                                                       .WithTriviaFrom(expression)
                                                                       .Parenthesize()
                                                                       .WithFormatterAnnotation();

                                            return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken));
                                        },
                                        GetEquivalenceKey(diagnostic, CodeFixIdentifiers.UseCoalesceExpression));

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

                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.CreateSingletonArray) &&
                        type?.IsErrorType() == false &&
                        !type.Equals(convertedType) &&
                        convertedType.IsArrayType())
                    {
                        var arrayType = (IArrayTypeSymbol)convertedType;

                        if (semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                        {
                            CodeAction codeAction = CodeAction.Create(
                                "Create singleton array",
                                cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken),
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.CreateSingletonArray));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ConstantValueCannotBeConverted:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseUncheckedExpression))
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Use 'unchecked'",
                        cancellationToken =>
                        {
                            CheckedExpressionSyntax newNode = CSharpFactory.UncheckedExpression(expression.WithoutTrivia());

                            newNode = newNode.WithTriviaFrom(expression);

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

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

                case CompilerDiagnosticIdentifiers.ExpressionBeingAssignedMustBeConstant:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConstModifier))
                    {
                        break;
                    }

                    LocalDeclarationStatementSyntax localDeclarationStatement = GetLocalDeclarationStatement(expression);

                    if (localDeclarationStatement == null)
                    {
                        break;
                    }

                    SyntaxTokenList modifiers = localDeclarationStatement.Modifiers;

                    if (!modifiers.Contains(SyntaxKind.ConstKeyword))
                    {
                        break;
                    }

                    ModifiersCodeFixes.RemoveModifier(context, diagnostic, localDeclarationStatement, SyntaxKind.ConstKeyword);

                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotConvertNullToTypeBecauseItIsNonNullableValueType:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
                    {
                        break;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(expression, context.CancellationToken).ConvertedType;

                    if (typeSymbol?.SupportsExplicitDeclaration() == true)
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Replace 'null' with default value",
                            cancellationToken =>
                            {
                                ExpressionSyntax newNode = typeSymbol.ToDefaultValueSyntax(semanticModel, expression.SpanStart);

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

                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ResultOfExpressionIsAlwaysConstantSinceValueIsNeverEqualToNull:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConditionThatIsAlwaysEqualToTrueOrFalse))
                    {
                        break;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    if (!NullCheckExpression.TryCreate(expression, semanticModel, out NullCheckExpression nullCheck, context.CancellationToken))
                    {
                        break;
                    }

                    if (nullCheck.Kind != NullCheckKind.EqualsToNull &&
                        nullCheck.Kind != NullCheckKind.NotEqualsToNull)
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove condition",
                        cancellationToken =>
                        {
                            SyntaxNode newRoot = RemoveHelper.RemoveCondition(root, expression, nullCheck.Kind == NullCheckKind.NotEqualsToNull);

                            return(Task.FromResult(context.Document.WithSyntaxRoot(newRoot)));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);

                    break;
                }
                }
            }
        }
コード例 #35
0
        protected StatementSyntax GenerateByValueOutUnmarshalStatement(TypePositionInfo info, StubCodeContext context)
        {
            // Use ManagedSource and NativeDestination spans for by-value marshalling since we're just marshalling back the contents,
            // not the array itself.
            // This code is ugly since we're now enforcing readonly safety with ReadOnlySpan for all other scenarios,
            // but this is an uncommon case so we don't want to design the API around enabling just it.
            string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(info, context);
            string managedSpanIdentifier = MarshallerHelpers.GetManagedSpanIdentifier(info, context);

            // Span<TElement> <managedSpan> = MemoryMarshal.CreateSpan(ref Unsafe.AsRef(in <GetManagedValuesSource>.GetPinnableReference(), <numElements>));
            LocalDeclarationStatementSyntax managedValuesDeclaration = LocalDeclarationStatement(VariableDeclaration(
                                                                                                     GenericName(
                                                                                                         Identifier(TypeNames.System_Span),
                                                                                                         TypeArgumentList(
                                                                                                             SingletonSeparatedList(_elementInfo.ManagedType.Syntax))
                                                                                                         ),
                                                                                                     SingletonSeparatedList(VariableDeclarator(managedSpanIdentifier).WithInitializer(EqualsValueClause(
                                                                                                                                                                                          InvocationExpression(
                                                                                                                                                                                              MemberAccessExpression(
                                                                                                                                                                                                  SyntaxKind.SimpleMemberAccessExpression,
                                                                                                                                                                                                  ParseName(TypeNames.System_Runtime_InteropServices_MemoryMarshal),
                                                                                                                                                                                                  IdentifierName("CreateSpan")))
                                                                                                                                                                                          .WithArgumentList(
                                                                                                                                                                                              ArgumentList(
                                                                                                                                                                                                  SeparatedList(
                                                                                                                                                                                                      new[]
            {
                Argument(
                    InvocationExpression(
                        MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                               ParseName(TypeNames.System_Runtime_CompilerServices_Unsafe),
                                               IdentifierName("AsRef")),
                        ArgumentList(SingletonSeparatedList(
                                         Argument(
                                             InvocationExpression(
                                                 MemberAccessExpression(
                                                     SyntaxKind.SimpleMemberAccessExpression,
                                                     GetManagedValuesSource(info, context),
                                                     IdentifierName("GetPinnableReference")),
                                                 ArgumentList()))
                                         .WithRefKindKeyword(
                                             Token(SyntaxKind.InKeyword))))))
                .WithRefKindKeyword(
                    Token(SyntaxKind.RefKeyword)),
                Argument(
                    IdentifierName(numElementsIdentifier))
            }))))))));

            // Span<TUnmanagedElement> <nativeSpan> = <GetUnmanagedValuesDestination>
            string nativeSpanIdentifier = MarshallerHelpers.GetNativeSpanIdentifier(info, context);
            LocalDeclarationStatementSyntax unmanagedValuesDeclaration = LocalDeclarationStatement(VariableDeclaration(
                                                                                                       GenericName(
                                                                                                           Identifier(TypeNames.System_Span),
                                                                                                           TypeArgumentList(SingletonSeparatedList(_unmanagedElementType))),
                                                                                                       SingletonSeparatedList(
                                                                                                           VariableDeclarator(
                                                                                                               Identifier(nativeSpanIdentifier))
                                                                                                           .WithInitializer(EqualsValueClause(
                                                                                                                                GetUnmanagedValuesDestination(info, context))))));

            return(Block(
                       managedValuesDeclaration,
                       unmanagedValuesDeclaration,
                       GenerateContentsMarshallingStatement(
                           info,
                           context,
                           IdentifierName(numElementsIdentifier),
                           StubCodeContext.Stage.UnmarshalCapture,
                           StubCodeContext.Stage.Unmarshal)));
        }
コード例 #36
0
        private static async Task <Document> RefactorAsync(
            Document document,
            ForEachStatementSyntax forEachStatement,
            CancellationToken cancellationToken)
        {
            int position = forEachStatement.SpanStart;

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            string name = NameGenerator.Default.EnsureUniqueLocalName(DefaultNames.EnumeratorVariable, semanticModel, position, cancellationToken: cancellationToken);

            InvocationExpressionSyntax expression = SimpleMemberInvocationExpression(forEachStatement.Expression.Parenthesize(), IdentifierName(WellKnownMemberNames.GetEnumeratorMethodName));

            VariableDeclarationSyntax variableDeclaration = VariableDeclaration(VarType(), Identifier(name).WithRenameAnnotation(), expression);

            MemberAccessExpressionSyntax currentExpression = SimpleMemberAccessExpression(IdentifierName(name), IdentifierName("Current"));

            ILocalSymbol localSymbol = semanticModel.GetDeclaredSymbol(forEachStatement, cancellationToken);

            StatementSyntax statement = forEachStatement.Statement;

            StatementSyntax newStatement = statement.ReplaceNodes(
                statement
                .DescendantNodes()
                .Where(node => node.IsKind(SyntaxKind.IdentifierName) && SymbolEqualityComparer.Default.Equals(localSymbol, semanticModel.GetSymbol(node, cancellationToken))),
                (node, _) => currentExpression.WithTriviaFrom(node));

            WhileStatementSyntax whileStatement = WhileStatement(
                SimpleMemberInvocationExpression(IdentifierName(name), IdentifierName("MoveNext")),
                newStatement);

            if (semanticModel
                .GetSpeculativeMethodSymbol(position, expression)?
                .ReturnType
                .Implements(SpecialType.System_IDisposable, allInterfaces: true) == true)
            {
                UsingStatementSyntax usingStatement = UsingStatement(
                    variableDeclaration,
                    default(ExpressionSyntax),
                    Block(whileStatement));

                usingStatement = usingStatement
                                 .WithLeadingTrivia(forEachStatement.GetLeadingTrivia())
                                 .WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(forEachStatement, usingStatement, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                LocalDeclarationStatementSyntax localDeclaration = LocalDeclarationStatement(variableDeclaration)
                                                                   .WithLeadingTrivia(forEachStatement.GetLeadingTrivia())
                                                                   .WithFormatterAnnotation();

                var newStatements = new StatementSyntax[] { localDeclaration, whileStatement.WithFormatterAnnotation() };

                if (forEachStatement.IsEmbedded())
                {
                    BlockSyntax block = Block(newStatements).WithFormatterAnnotation();

                    return(await document.ReplaceNodeAsync(forEachStatement, block, cancellationToken).ConfigureAwait(false));
                }

                return(await document.ReplaceNodeAsync(forEachStatement, newStatements, cancellationToken).ConfigureAwait(false));
            }
        }
コード例 #37
0
 /// <summary>
 /// Creates a new <see cref="Syntax.ModifierListInfo"/> from the specified local declaration statement.
 /// </summary>
 /// <param name="localDeclarationStatement"></param>
 /// <returns></returns>
 public static ModifierListInfo ModifierListInfo(LocalDeclarationStatementSyntax localDeclarationStatement)
 {
     return(Syntax.ModifierListInfo.Create(localDeclarationStatement));
 }
コード例 #38
0
 /// <summary>
 /// Creates a new <see cref="Syntax.SingleLocalDeclarationStatementInfo"/> from the specified local declaration statement.
 /// </summary>
 /// <param name="localDeclarationStatement"></param>
 /// <param name="allowMissing"></param>
 /// <returns></returns>
 public static SingleLocalDeclarationStatementInfo SingleLocalDeclarationStatementInfo(
     LocalDeclarationStatementSyntax localDeclarationStatement,
     bool allowMissing = false)
 {
     return(Syntax.SingleLocalDeclarationStatementInfo.Create(localDeclarationStatement, allowMissing));
 }
コード例 #39
0
 protected abstract void CompileLocalDeclarationStatement(LocalDeclarationStatementSyntax statement);