Пример #1
0
            public override void VisitAssignmentExpression([NotNull] IAssignmentExpression operation)
            {
                if (operation.Target is ILocalReferenceExpression targetLocal && local.Equals(targetLocal.Local))
                {
                    TrySetEvent(operation.Value);
                }

                base.VisitAssignmentExpression(operation);
            }
Пример #2
0
            public override void VisitSimpleAssignment([NotNull] ISimpleAssignmentOperation operation)
            {
                if (operation.Target is ILocalReferenceOperation targetLocal && local.Equals(targetLocal.Local))
                {
                    TrySetEvent(operation.Value);
                }

                base.VisitSimpleAssignment(operation);
            }
Пример #3
0
                public override void VisitVariableDeclarator([NotNull] IVariableDeclaratorOperation operation)
                {
                    base.VisitVariableDeclarator(operation);

                    if (currentLocal.Equals(operation.Symbol) && operation.Initializer != null)
                    {
                        AnalyzeAssignmentValue(operation.Initializer.Value);
                    }
                }
                public override void VisitVariableDeclarationStatement([NotNull] IVariableDeclarationStatement operation)
                {
                    base.VisitVariableDeclarationStatement(operation);

                    foreach (IVariableDeclaration variable in operation.Declarations)
                    {
                        if (currentLocal.Equals(variable.Variables.Single()))
                        {
                            AnalyzeAssignmentValue(variable.Initializer);
                        }
                    }
                }
                public override void VisitVariableDeclarator([NotNull] IVariableDeclaratorOperation operation)
                {
                    base.VisitVariableDeclarator(operation);

                    if (currentLocal.Equals(operation.Symbol) && EndsBeforeMaxLocation(operation))
                    {
                        IVariableInitializerOperation initializer = operation.GetVariableInitializer();
                        if (initializer != null)
                        {
                            AnalyzeAssignmentValue(initializer.Value);
                        }
                    }
                }
Пример #6
0
        private static LocalInfo FindInitializedVariable(
            IdentifierNameSyntax identifierName,
            VariableDeclaratorSyntax variableDeclarator,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            string name = identifierName.Identifier.ValueText;

            ILocalSymbol localSymbol = null;

            if (string.Equals(variableDeclarator.Identifier.ValueText, name, StringComparison.Ordinal))
            {
                if (localSymbol == null)
                {
                    localSymbol = semanticModel.GetSymbol(identifierName, cancellationToken) as ILocalSymbol;

                    if (localSymbol == null)
                    {
                        return(default(LocalInfo));
                    }
                }

                if (localSymbol.Equals(semanticModel.GetDeclaredSymbol(variableDeclarator, cancellationToken)))
                {
                    return(new LocalInfo(variableDeclarator, localSymbol));
                }
            }

            return(default(LocalInfo));
        }
Пример #7
0
        private static IEnumerable <int> GetAssignedIndexes(IEnumerable <StatementSyntax> statements, ILocalSymbol symbol, SemanticModel semanticModel)
        {
            foreach (var statement in statements)
            {
                var assignment = statement as AssignmentStatementSyntax;
                if (assignment == null)
                {
                    yield break;
                }

                var invocation = assignment.Left as InvocationExpressionSyntax;
                if (invocation == null ||
                    invocation.ArgumentList == null ||
                    invocation.ArgumentList.Arguments.Count != 1)
                {
                    yield break;
                }

                var assignedSymbol = semanticModel.GetSymbolInfo(invocation.Expression).Symbol;
                if (!symbol.Equals(assignedSymbol))
                {
                    yield break;
                }

                var argument = invocation.ArgumentList.Arguments.First();
                var index    = GetConstantArgumentValue(argument, semanticModel);
                if (!index.HasValue)
                {
                    yield break;
                }

                yield return(index.Value);
            }
        }
Пример #8
0
        private static bool IsEndingWithDispose(SemanticModel semanticModel, List <StatementSyntax> insideUsing, ILocalSymbol disposableLocal)
        {
            var lastInUsingAsCall = (((insideUsing.LastOrDefault() as ExpressionStatementSyntax)?.Expression as InvocationExpressionSyntax)?.Expression as MemberAccessExpressionSyntax);

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

            var targetSymbol = semanticModel.GetSymbolInfo(lastInUsingAsCall.Expression);

            if (!disposableLocal.Equals(targetSymbol.Symbol))
            {
                return(false);
            }


            var dispose = semanticModel.Compilation.GetSpecialType(SpecialType.System_IDisposable).GetMembers("Dispose").Single();

            var calledMethod = semanticModel.GetSymbolInfo(lastInUsingAsCall).Symbol;

            if (!dispose.Equals(calledMethod))
            {
                return(false);
            }


            return(true);
        }
        private static bool IsAddedToFieldOrProperty(ILocalSymbol symbol, BlockSyntax block, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            using (var pooledInvocations = InvocationWalker.Borrow(block))
            {
                foreach (var invocation in pooledInvocations.Invocations)
                {
                    var method = semanticModel.GetSymbolSafe(invocation, cancellationToken) as IMethodSymbol;
                    if (method?.Name == "Add")
                    {
                        using (var nameWalker = IdentifierNameWalker.Borrow(invocation.ArgumentList))
                        {
                            foreach (var identifierName in nameWalker.IdentifierNames)
                            {
                                var argSymbol = semanticModel.GetSymbolSafe(identifierName, cancellationToken);
                                if (symbol.Equals(argSymbol))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
Пример #10
0
        private static VariableDeclaratorSyntax FindInitializedVariable(
            SeparatedSyntaxList <VariableDeclaratorSyntax> declarators,
            IdentifierNameSyntax identifierName,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            string name = identifierName.Identifier.ValueText;

            ILocalSymbol localSymbol = null;

            foreach (VariableDeclaratorSyntax declarator in declarators)
            {
                if (name == declarator.Identifier.ValueText)
                {
                    if (localSymbol == null)
                    {
                        localSymbol = semanticModel.GetSymbol(identifierName, cancellationToken) as ILocalSymbol;

                        if (localSymbol == null)
                        {
                            return(null);
                        }
                    }

                    if (localSymbol.Equals(semanticModel.GetDeclaredSymbol(declarator, cancellationToken)))
                    {
                        return(declarator);
                    }
                }
            }

            return(null);
        }
Пример #11
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, 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.Kind() == SyntaxKind.IdentifierName && localSymbol.Equals(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() };

                return(await document.ReplaceNodeAsync(forEachStatement, newStatements, cancellationToken).ConfigureAwait(false));
            }
        }
Пример #12
0
        public static void AnalyzeCatchClause(SyntaxNodeAnalysisContext context)
        {
            var catchClause = (CatchClauseSyntax)context.Node;

            BlockSyntax block = catchClause.Block;

            if (block == null)
            {
                return;
            }

            CatchDeclarationSyntax declaration = catchClause.Declaration;

            if (declaration == null)
            {
                return;
            }

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

            ILocalSymbol symbol = semanticModel.GetDeclaredSymbol(declaration, cancellationToken);

            if (symbol?.IsErrorType() != false)
            {
                return;
            }

            //TODO: SyntaxWalker
            foreach (SyntaxNode node in block.DescendantNodes(descendIntoChildren: f => f.Kind() != SyntaxKind.CatchClause))
            {
                if (node.Kind() != SyntaxKind.ThrowStatement)
                {
                    continue;
                }

                var throwStatement          = (ThrowStatementSyntax)node;
                ExpressionSyntax expression = throwStatement.Expression;

                if (expression == null)
                {
                    continue;
                }

                ISymbol expressionSymbol = semanticModel.GetSymbol(expression, cancellationToken);

                if (!symbol.Equals(expressionSymbol))
                {
                    continue;
                }

                context.ReportDiagnostic(
                    DiagnosticDescriptors.RemoveOriginalExceptionFromThrowStatement,
                    expression);
            }
        }
            private bool IsAccessedOutOfScope(SyntaxNode scope)
            {
                Debug.Assert(scope != null);

                var localStatementStart = _localStatement.SpanStart;
                var comparisonSpanStart = _comparison.SpanStart;
                var variableName        = _localSymbol.Name;
                var scopeSpan           = scope.Span;

                // Iterate over all descendent nodes to find possible out-of-scope references.
                foreach (var descendentNode in _enclosingBlock.DescendantNodes())
                {
                    var descendentNodeSpanStart = descendentNode.SpanStart;
                    if (descendentNodeSpanStart <= localStatementStart)
                    {
                        // We're not interested in nodes that are apeared before
                        // the local declaration statement. It's either an error
                        // or not the local reference we're looking for.
                        continue;
                    }

                    if (
                        descendentNodeSpanStart >= comparisonSpanStart &&
                        scopeSpan.Contains(descendentNode.Span)
                        )
                    {
                        // If this is in the scope and after null-check, we don't bother checking the symbol.
                        continue;
                    }

                    if (
                        descendentNode.IsKind(
                            SyntaxKind.IdentifierName,
                            out IdentifierNameSyntax identifierName
                            ) &&
                        identifierName.Identifier.ValueText == variableName &&
                        _localSymbol.Equals(
                            _semanticModel.GetSymbolInfo(identifierName, _cancellationToken).Symbol
                            )
                        )
                    {
                        // If we got here, it means we have a local
                        // reference out of scope of the pattern variable.
                        return(true);
                    }
                }

                // Either no reference were found, or all
                // references were inside the given scope.
                return(false);
            }
Пример #14
0
        private static bool OnlyUsedToAccessTupleFields(
            SemanticModel semanticModel,
            SyntaxNode searchScope,
            ILocalSymbol local,
            ArrayBuilder <MemberAccessExpressionSyntax> memberAccessLocations,
            CancellationToken cancellationToken
            )
        {
            var localName = local.Name;

            foreach (
                var identifierName in searchScope.DescendantNodes().OfType <IdentifierNameSyntax>()
                )
            {
                if (identifierName.Identifier.ValueText == localName)
                {
                    var symbol = semanticModel
                                 .GetSymbolInfo(identifierName, cancellationToken)
                                 .GetAnySymbol();
                    if (local.Equals(symbol))
                    {
                        if (!(identifierName.Parent is MemberAccessExpressionSyntax memberAccess))
                        {
                            // We referenced the local in a location where we're not accessing a
                            // field off of it.  i.e. Console.WriteLine(tupleLocal);
                            return(false);
                        }

                        var member = semanticModel
                                     .GetSymbolInfo(memberAccess, cancellationToken)
                                     .GetAnySymbol();
                        if (!(member is IFieldSymbol field))
                        {
                            // Accessed some non-field member of it (like .ToString()).
                            return(false);
                        }

                        if (field.IsImplicitlyDeclared)
                        {
                            // They're referring to .Item1-.ItemN.  We can't update this to refer to the local
                            return(false);
                        }

                        memberAccessLocations.Add(memberAccess);
                    }
                }
            }

            return(true);
        }
Пример #15
0
        private static IEnumerable <IdentifierNameSyntax> GetVariableReferences(
            ForEachStatementSyntax forEachStatement,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            ILocalSymbol symbol = semanticModel.GetDeclaredSymbol(forEachStatement, cancellationToken);

            foreach (SyntaxNode node in forEachStatement.Statement.DescendantNodes())
            {
                if (node.IsKind(SyntaxKind.IdentifierName) &&
                    symbol.Equals(semanticModel.GetSymbol(node, cancellationToken)))
                {
                    yield return((IdentifierNameSyntax)node);
                }
            }
        }
        private static bool IsPassedAsArgument(StatementSyntax statement, SemanticModel semanticModel, ILocalSymbol identitySymbol)
        {
            if (statement == null)
            {
                return(false);
            }
            var args = statement.DescendantNodes().OfKind <ArgumentSyntax>(SyntaxKind.Argument);

            foreach (var arg in args)
            {
                var argSymbol = semanticModel.GetSymbolInfo(arg.Expression).Symbol;
                if (identitySymbol.Equals(argSymbol))
                {
                    return(true);
                }
            }
            return(false);
        }
        private static IdentifierNameSyntax FindLastReference(
            ILocalSymbol symbol,
            SyntaxNode node,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            IdentifierNameSyntax lastReference = null;

            foreach (SyntaxNode descendant in node.DescendantNodes())
            {
                if ((descendant is IdentifierNameSyntax identifierName) &&
                    symbol.Equals(semanticModel.GetSymbol(identifierName, cancellationToken)))
                {
                    lastReference = identifierName;
                }
            }

            return(lastReference);
        }
        public static void Analyze(SyntaxNodeAnalysisContext context, CatchClauseSyntax catchClause)
        {
            CatchDeclarationSyntax declaration = catchClause.Declaration;

            if (declaration != null)
            {
                BlockSyntax block = catchClause.Block;

                if (block != null)
                {
                    ILocalSymbol symbol = context
                                          .SemanticModel
                                          .GetDeclaredSymbol(catchClause.Declaration, context.CancellationToken);

                    if (symbol != null)
                    {
                        foreach (SyntaxNode node in block.DescendantNodes(f => !f.IsKind(SyntaxKind.CatchClause)))
                        {
                            if (node.IsKind(SyntaxKind.ThrowStatement))
                            {
                                var throwStatement = (ThrowStatementSyntax)node;
                                if (throwStatement.Expression != null)
                                {
                                    ISymbol expressionSymbol = context
                                                               .SemanticModel
                                                               .GetSymbol(throwStatement.Expression, context.CancellationToken);

                                    if (expressionSymbol != null &&
                                        symbol.Equals(expressionSymbol))
                                    {
                                        context.ReportDiagnostic(
                                            DiagnosticDescriptors.RemoveOriginalExceptionFromThrowStatement,
                                            throwStatement.Expression);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #19
0
        private static bool IsAssignedToField(ExpressionStatementSyntax expressionStatement, SemanticModel semanticModel, ILocalSymbol identitySymbol)
        {
            if (expressionStatement == null)
            {
                return(false);
            }
            if (!expressionStatement.Expression.IsKind(SyntaxKind.SimpleAssignmentExpression))
            {
                return(false);
            }
            var assignment       = (AssignmentExpressionSyntax)expressionStatement.Expression;
            var assignmentTarget = semanticModel.GetSymbolInfo(assignment.Left).Symbol;

            if (assignmentTarget?.Kind != SymbolKind.Field)
            {
                return(false);
            }
            var assignmentSource = semanticModel.GetSymbolInfo(assignment.Right).Symbol;

            return(identitySymbol.Equals(assignmentSource));
        }
            private bool IsExIsCoroutineStoppedExceptionExp(ExpressionSyntax exp,
                                                            ILocalSymbol exceptionSymbol,
                                                            SemanticModel model)
            {
                BinaryExpressionSyntax binExp = exp as BinaryExpressionSyntax;

                if (binExp == null || binExp.OperatorToken.Kind() != SyntaxKind.IsKeyword)
                {
                    return(false);
                }

                ILocalSymbol     leftSymbol  = model.GetSymbolInfo(binExp.Left).Symbol as ILocalSymbol;
                INamedTypeSymbol rightSymbol =
                    model.GetSymbolInfo(binExp.Right).Symbol as INamedTypeSymbol;

                if (leftSymbol != null && leftSymbol.Equals(exceptionSymbol) &&
                    rightSymbol == CoroutineStoppedExceptionType)
                {
                    return(true);
                }
                return(false);
            }
        private void AnalyzeSyntaxNode(SyntaxNodeAnalysisContext context)
        {
            if (GeneratedCodeAnalyzer?.IsGeneratedCode(context) == true)
            {
                return;
            }

            var catchClause = (CatchClauseSyntax)context.Node;

            if (catchClause.Declaration == null || catchClause.Block == null)
            {
                return;
            }

            ILocalSymbol symbol = context
                                  .SemanticModel
                                  .GetDeclaredSymbol(catchClause.Declaration, context.CancellationToken);

            if (symbol != null)
            {
                foreach (SyntaxNode node in catchClause.Block.DescendantNodes(f => !f.IsKind(SyntaxKind.CatchClause)))
                {
                    if (node.IsKind(SyntaxKind.ThrowStatement))
                    {
                        var throwStatement = (ThrowStatementSyntax)node;
                        if (throwStatement.Expression != null)
                        {
                            ISymbol expressionSymbol = context
                                                       .SemanticModel
                                                       .GetSymbolInfo(throwStatement.Expression, context.CancellationToken)
                                                       .Symbol;

                            if (expressionSymbol != null &&
                                symbol.Equals(expressionSymbol))
                            {
                                context.ReportDiagnostic(
                                    DiagnosticDescriptors.RemoveOriginalExceptionFromThrowStatement,
                                    throwStatement.Expression.GetLocation());
                            }
                        }
                    }
                }
            }

            if (catchClause.Declaration.Type != null &&
                catchClause.Block.Statements.Count == 0)
            {
                ITypeSymbol typeSymbol = context
                                         .SemanticModel
                                         .GetTypeInfo(catchClause.Declaration.Type, context.CancellationToken)
                                         .Type;

                if (typeSymbol != null)
                {
                    INamedTypeSymbol exceptionTypeSymbol = context.GetTypeByMetadataName("System.Exception");

                    if (typeSymbol.Equals(exceptionTypeSymbol))
                    {
                        context.ReportDiagnostic(
                            DiagnosticDescriptors.AvoidEmptyCatchClauseThatCatchesSystemException,
                            catchClause.CatchKeyword.GetLocation());
                    }
                }
            }
        }
 private static bool IsPassedAsArgument(StatementSyntax statement, SemanticModel semanticModel, ILocalSymbol identitySymbol)
 {
     if (statement == null) return false;
     var args = statement.DescendantNodes().OfKind<ArgumentSyntax>(SyntaxKind.Argument);
     foreach (var arg in args)
     {
         var argSymbol = semanticModel.GetSymbolInfo(arg.Expression).Symbol;
         if (identitySymbol.Equals(argSymbol)) return true;
     }
     return false;
 }
        private static bool IsUsedAfter(ILocalSymbol local, InvocationExpressionSyntax invocation, SyntaxNodeAnalysisContext context, out IReadOnlyList <Location> locations)
        {
            if (local.TrySingleDeclaration(context.CancellationToken, out var declaration) &&
                declaration.TryFirstAncestor(out BlockSyntax block))
            {
                List <Location> temp = null;
                using (var walker = IdentifierNameWalker.Borrow(block))
                {
                    foreach (var identifierName in walker.IdentifierNames)
                    {
                        if (identifierName.Identifier.ValueText == local.Name &&
                            invocation.IsExecutedBefore(identifierName) == ExecutedBefore.Yes &&
                            context.SemanticModel.TryGetSymbol(identifierName, context.CancellationToken, out ILocalSymbol candidate) &&
                            local.Equals(candidate) &&
                            !IsAssigned(identifierName) &&
                            !IsReassigned(identifierName))
                        {
                            if (temp == null)
                            {
                                temp = new List <Location>();
                            }

                            temp.Add(identifierName.GetLocation());
                        }
                    }

                    locations = temp;
                    return(locations != null);
                }
            }

            locations = null;
            return(false);

            bool IsAssigned(IdentifierNameSyntax identifier)
            {
                switch (identifier.Parent)
                {
                case AssignmentExpressionSyntax assignment:
                    return(assignment.Left == identifier);

                case ArgumentSyntax argument when argument.RefOrOutKeyword.IsKind(SyntaxKind.OutKeyword):
                    return(true);
                }

                return(false);
            }

            bool IsReassigned(ExpressionSyntax location)
            {
                using (var walker = MutationWalker.For(local, context.SemanticModel, context.CancellationToken))
                {
                    foreach (var mutation in walker.All())
                    {
                        if (mutation.TryFirstAncestorOrSelf(out ExpressionSyntax expression) &&
                            invocation.IsExecutedBefore(expression) != ExecutedBefore.No &&
                            expression.IsExecutedBefore(location) != ExecutedBefore.No)
                        {
                            return(true);
                        }
                    }
                }

                return(false);
            }
        }
        private static IEnumerable<int> GetAssignedIndexes(IEnumerable<StatementSyntax> statements, ILocalSymbol symbol, SemanticModel semanticModel)
        {
            foreach (var statement in statements)
            {
                var assignment = statement as AssignmentStatementSyntax;
                if (assignment == null)
                {
                    yield break;
                }

                var invocation = assignment.Left as InvocationExpressionSyntax;
                if (invocation?.ArgumentList == null ||
                    invocation.ArgumentList.Arguments.Count != 1)
                {
                    yield break;
                }

                var assignedSymbol = semanticModel.GetSymbolInfo(invocation.Expression).Symbol;
                if (!symbol.Equals(assignedSymbol))
                {
                    yield break;
                }

                var argument = invocation.ArgumentList.Arguments.First();
                var index = GetConstantArgumentValue(argument, semanticModel);
                if (!index.HasValue)
                {
                    yield break;
                }

                yield return index.Value;
            }
        }
Пример #25
0
        private bool WouldCauseDefiniteAssignmentErrors(
            SemanticModel semanticModel,
            VariableDeclarationSyntax localDeclaration,
            VariableDeclaratorSyntax localDeclarator,
            BlockSyntax enclosingBlock,
            ILocalSymbol outLocalSymbol,
            CancellationToken cancellationToken)
        {
            // See if we have something like:
            //
            //      int i = 0;
            //      if (Goo() || Bar(out i))
            //      {
            //          Console.WriteLine(i);
            //      }
            //
            // In this case, inlining the 'i' would cause it to longer be definitely
            // assigned in the WriteLine invocation.

            // Find all the current read-references to the local.
            var query = from t in enclosingBlock.DescendantTokens()
                        where t.Kind() == SyntaxKind.IdentifierToken
                        where t.ValueText == outLocalSymbol.Name
                        let id = t.Parent as IdentifierNameSyntax
                                 where id != null
                                 where !id.IsOnlyWrittenTo()
                                 let symbol = semanticModel.GetSymbolInfo(id).GetAnySymbol()
                                              where outLocalSymbol.Equals(symbol)
                                              select id;

            var references = query.ToImmutableArray <SyntaxNode>();

            var root = semanticModel.SyntaxTree.GetCompilationUnitRoot(cancellationToken);

            // Ensure we can track the references and the local variable as we make edits
            // to the tree.
            var rootWithTrackedNodes = root.TrackNodes(
                references.Concat(ImmutableArray.Create <SyntaxNode>(localDeclarator, localDeclaration, enclosingBlock)));

            // Now, take the local variable and remove it's initializer.  Then go to all
            // the locations where we read from it.  If they're definitely assigned, then
            // that means the out-var did it's work and assigned the variable across all
            // paths. If it's not definitely assigned, then we can't inline this variable.
            var currentLocalDeclarator  = rootWithTrackedNodes.GetCurrentNode(localDeclarator);
            var currentLocalDeclaration = rootWithTrackedNodes.GetCurrentNode(localDeclaration);
            var updatedDeclaration      = currentLocalDeclaration
                                          .ReplaceNode(currentLocalDeclarator, currentLocalDeclarator.WithInitializer(null));

            // If the declaration was a "var" declaration, then replace "var" with the actual
            // type of the local.  This way we don't get a "'var v' requires an initializer" which
            // will suppress the message about definite assignment later.
            if (updatedDeclaration.Type.IsVar)
            {
                updatedDeclaration = updatedDeclaration.WithType(
                    outLocalSymbol.Type.GenerateTypeSyntax());
            }

            var rootWithoutInitializer = rootWithTrackedNodes.ReplaceNode(
                currentLocalDeclaration, updatedDeclaration);

            var rootWithoutInitializerTree = root.SyntaxTree.WithRootAndOptions(
                rootWithoutInitializer, root.SyntaxTree.Options);

            // Fork the compilation so we can do this analysis.
            var newCompilation = semanticModel.Compilation.ReplaceSyntaxTree(
                root.SyntaxTree, rootWithoutInitializerTree);
            var newSemanticModel = newCompilation.GetSemanticModel(rootWithoutInitializerTree);

            // NOTE: there is no current compiler API to determine if a variable is definitely
            // assigned or not.  So, for now, we just get diagnostics for this block and see if
            // we get any definite assignment errors where we have a reference to the symbol. If
            // so, then we don't offer the fix.

            rootWithoutInitializer = (CompilationUnitSyntax)rootWithoutInitializerTree.GetRoot(cancellationToken);
            var currentBlock = rootWithoutInitializer.GetCurrentNode(enclosingBlock);
            var diagnostics  = newSemanticModel.GetDiagnostics(currentBlock.Span, cancellationToken);

            var diagnosticSpans = diagnostics.Where(d => d.Id == CS0165)
                                  .Select(d => d.Location.SourceSpan)
                                  .Distinct();

            var newReferenceSpans = rootWithoutInitializer.GetCurrentNodes <SyntaxNode>(references)
                                    .Select(n => n.Span)
                                    .Distinct();

            return(diagnosticSpans.Intersect(newReferenceSpans).Any());
        }
 private static bool IsAssignedToField(ExpressionStatementSyntax expressionStatement, SemanticModel semanticModel, ILocalSymbol identitySymbol)
 {
     if (expressionStatement == null) return false;
     if (!expressionStatement.Expression.IsKind(SyntaxKind.SimpleAssignmentExpression)) return false;
     var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression;
     var assignmentTarget = semanticModel.GetSymbolInfo(assignment.Left).Symbol;
     if (assignmentTarget?.Kind != SymbolKind.Field) return false;
     var assignmentSource = semanticModel.GetSymbolInfo(assignment.Right).Symbol;
     return (identitySymbol.Equals(assignmentSource));
 }