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

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

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

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

			newBody = newBody.WithAdditionalAnnotations(Formatter.Annotation);

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

			var newRoot = document.Root.ReplaceNode(oldLambda, newLambda);
			return document.Document.WithSyntaxRoot(newRoot);
		}
        protected override async Task<InsertionPoint> GetInsertionPointAsync(SemanticDocument document, int position, CancellationToken cancellationToken)
        {
            //Contract.ThrowIfFalse(position >= 0);

            var root = await document.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var basePosition = root.FindToken(position);

            var memberNode = basePosition.GetAncestor<MemberDeclarationSyntax>();
//            Contract.ThrowIfNull(memberNode);
//            Contract.ThrowIfTrue(memberNode.Kind() == SyntaxKind.NamespaceDeclaration);

            var globalStatement = memberNode as GlobalStatementSyntax;
            if (globalStatement != null)
            {
                // check whether we are extracting whole global statement out
                if (this.OriginalSelectionResult.FinalSpan.Contains(memberNode.Span))
                {
                    return await InsertionPoint.CreateAsync(document, globalStatement.Parent, cancellationToken).ConfigureAwait(false);
                }

                return await InsertionPoint.CreateAsync(document, globalStatement.Statement, cancellationToken).ConfigureAwait(false);
            }

            return await InsertionPoint.CreateAsync(document, memberNode, cancellationToken).ConfigureAwait(false);
        }
Пример #3
0
 public CSharpSelectionValidator(
     SemanticDocument document,
     TextSpan textSpan,
     OptionSet options) :
     base(document, textSpan, options)
 {
 }
 public static async Task<InsertionPoint> CreateAsync(SemanticDocument document, SyntaxNode node, CancellationToken cancellationToken)
 {
     var root = document.Root;
     var annotation = new SyntaxAnnotation();
     var newRoot = root.AddAnnotations(SpecializedCollections.SingletonEnumerable(Tuple.Create(node, annotation)));
     return new InsertionPoint(await document.WithSyntaxRootAsync(newRoot, cancellationToken).ConfigureAwait(false), annotation);
 }
            public AnalyzerResult(
				SemanticDocument document,
                IEnumerable<ITypeParameterSymbol> typeParametersInDeclaration,
                IEnumerable<ITypeParameterSymbol> typeParametersInConstraintList,
                IList<VariableInfo> variables,
                VariableInfo variableToUseAsReturnValue,
                ITypeSymbol returnType,
                bool awaitTaskReturn,
                bool instanceMemberIsUsed,
                bool endOfSelectionReachable,
                OperationStatus status)
            {
                var semanticModel = document.SemanticModel;

                this.UseInstanceMember = instanceMemberIsUsed;
                this.EndOfSelectionReachable = endOfSelectionReachable;
                this.AwaitTaskReturn = awaitTaskReturn;
                this.SemanticDocument = document;
                _typeParametersInDeclaration = typeParametersInDeclaration.Select(s => semanticModel.ResolveType(s)).ToList();
                _typeParametersInConstraintList = typeParametersInConstraintList.Select(s => semanticModel.ResolveType(s)).ToList();
                _variables = variables;
                this.ReturnType = semanticModel.ResolveType(returnType);
                _variableToUseAsReturnValue = variableToUseAsReturnValue;
                this.Status = status;
            }
            public TriviaResult(SemanticDocument document, ITriviaSavedResult result, int endOfLineKind, int whitespaceKind)
            {
                this.SemanticDocument = document;

                _result = result;
                _endOfLineKind = endOfLineKind;
                _whitespaceKind = whitespaceKind;
            }
        private InsertionPoint(SemanticDocument document, SyntaxAnnotation annotation)
        {
            //Contract.ThrowIfNull(document);
            //Contract.ThrowIfNull(annotation);

            this.SemanticDocument = document;
            _annotation = annotation;
            _context = CreateLazyContextNode();
        }
 public Rewriter(
     LambdaSimplifierCodeRefactoringProvider codeIssueProvider,
     SemanticDocument document,
     Func<SyntaxNode, bool> predicate,
     CancellationToken cancellationToken)
 {
     _codeIssueProvider = codeIssueProvider;
     _document = document;
     _predicate = predicate;
     _cancellationToken = cancellationToken;
 }
 public ExpressionResult(
     OperationStatus status,
     TextSpan originalSpan,
     TextSpan finalSpan,
     OptionSet options,
     bool selectionInExpression,
     SemanticDocument document,
     SyntaxAnnotation firstTokenAnnotation,
     SyntaxAnnotation lastTokenAnnotation) :
     base(status, originalSpan, finalSpan, options, selectionInExpression, document, firstTokenAnnotation, lastTokenAnnotation)
 {
 }
        protected override Task<Document> IntroduceQueryLocalAsync(
            SemanticDocument document, ExpressionSyntax expression, bool allOccurrences, CancellationToken cancellationToken)
        {
            var oldOutermostQuery = expression.GetAncestorsOrThis<QueryExpressionSyntax>().LastOrDefault();

            var newLocalNameToken = GenerateUniqueLocalName(
                document, expression, isConstant: false, 
                container: oldOutermostQuery, cancellationToken: cancellationToken);
            var newLocalName = SyntaxFactory.IdentifierName(newLocalNameToken);

            var letClause = SyntaxFactory.LetClause(
                newLocalNameToken.WithAdditionalAnnotations(RenameAnnotation.Create()),
                expression).WithAdditionalAnnotations(Formatter.Annotation);

            var matches = FindMatches(document, expression, document, oldOutermostQuery, allOccurrences, cancellationToken);
            var innermostClauses = new HashSet<SyntaxNode>(
                matches.Select(expr => expr.GetAncestorsOrThis<SyntaxNode>().First(IsAnyQueryClause)));

            if (innermostClauses.Count == 1)
            {
                // If there was only one match, or all the matches came from the same
                // statement, then we want to place the declaration right above that
                // statement. Note: we special case this because the statement we are going
                // to go above might not be in a block and we may have to generate it
                return Task.FromResult(IntroduceQueryLocalForSingleOccurrence(
                    document, expression, newLocalName, letClause, allOccurrences, cancellationToken));
            }

            var oldInnerMostCommonQuery = matches.FindInnermostCommonNode<QueryExpressionSyntax>();
            var newInnerMostQuery = Rewrite(
                document, expression, newLocalName, document, oldInnerMostCommonQuery, allOccurrences, cancellationToken);

            var allAffectedClauses = new HashSet<SyntaxNode>(matches.SelectMany(expr => expr.GetAncestorsOrThis<SyntaxNode>().Where(IsAnyQueryClause)));

            var oldClauses = oldInnerMostCommonQuery.GetAllClauses();
            var newClauses = newInnerMostQuery.GetAllClauses();

            var firstClauseAffectedInQuery = oldClauses.First(allAffectedClauses.Contains);
            var firstClauseAffectedIndex = oldClauses.IndexOf(firstClauseAffectedInQuery);

            var finalClauses = newClauses.Take(firstClauseAffectedIndex)
                                         .Concat(letClause)
                                         .Concat(newClauses.Skip(firstClauseAffectedIndex)).ToList();

            var finalQuery = newInnerMostQuery.WithAllClauses(finalClauses);
            var newRoot = document.Root.ReplaceNode(oldInnerMostCommonQuery, finalQuery);

            return Task.FromResult(document.Document.WithSyntaxRoot(newRoot));
        }
		protected override Task<Document> IntroduceLocalAsync(
			SemanticDocument document,
			ExpressionSyntax expression,
			bool allOccurrences,
			bool isConstant,
			CancellationToken cancellationToken)
		{
			var options = document.Project.Solution.Workspace.Options;

			var newLocalNameToken = (SyntaxToken)GenerateUniqueLocalName(document, expression, isConstant, cancellationToken);
			var newLocalName = SyntaxFactory.IdentifierName(newLocalNameToken);

			var modifiers = isConstant
				? SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ConstKeyword))
			                   : default(SyntaxTokenList);

			var declarationStatement = SyntaxFactory.LocalDeclarationStatement(
				modifiers,
				SyntaxFactory.VariableDeclaration(
					this.GetTypeSyntax(document, expression, isConstant, options, cancellationToken),
					SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator(
						newLocalNameToken.WithAdditionalAnnotations(RenameAnnotation.Create()),
						null,
						SyntaxFactory.EqualsValueClause(expression.WithoutTrailingTrivia().WithoutLeadingTrivia())))));

			var anonymousMethodParameters = GetAnonymousMethodParameters(document, expression, cancellationToken);
			var lambdas = anonymousMethodParameters.SelectMany(p => p.ContainingSymbol.DeclaringSyntaxReferences.Select(r => r.GetSyntax(cancellationToken)).AsEnumerable())
			                                       .Where(n => n is ParenthesizedLambdaExpressionSyntax || n is SimpleLambdaExpressionSyntax)
			                                       .ToSet();

			var parentLambda = GetParentLambda(expression, lambdas);

			if (parentLambda != null)
			{
				return Task.FromResult(IntroduceLocalDeclarationIntoLambda(
					document, expression, newLocalName, declarationStatement, parentLambda, allOccurrences, cancellationToken));
			}
			else if (IsInExpressionBodiedMember(expression))
			{
				return Task.FromResult(RewriteExpressionBodiedMemberAndIntroduceLocalDeclaration(
					document, expression, newLocalName, declarationStatement, allOccurrences, cancellationToken));
			}
			else
			{
				return IntroduceLocalDeclarationIntoBlockAsync(
					document, expression, newLocalName, declarationStatement, allOccurrences, cancellationToken);
			}
		}
        protected override async Task<Document> IntroduceLocalAsync(
            SemanticDocument document,
            ExpressionSyntax expression,
            bool allOccurrences,
            bool isConstant,
            CancellationToken cancellationToken)
        {
            var containerToGenerateInto = GetContainerToGenerateInto(document, expression, cancellationToken);

            var newLocalNameToken = GenerateUniqueLocalName(
                document, expression, isConstant, containerToGenerateInto, cancellationToken);
            var newLocalName = SyntaxFactory.IdentifierName(newLocalNameToken);

            var modifiers = isConstant
                ? SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ConstKeyword))
                : default(SyntaxTokenList);

            var options = await document.Document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);

            var declarationStatement = SyntaxFactory.LocalDeclarationStatement(
                modifiers,
                SyntaxFactory.VariableDeclaration(
                    this.GetTypeSyntax(document, options, expression, isConstant, cancellationToken),
                    SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator(
                        newLocalNameToken.WithAdditionalAnnotations(RenameAnnotation.Create()),
                        null,
                        SyntaxFactory.EqualsValueClause(expression.WithoutTrailingTrivia().WithoutLeadingTrivia())))));

            switch (containerToGenerateInto)
            {
                case BlockSyntax block:
                    return await IntroduceLocalDeclarationIntoBlockAsync(
                        document, block, expression, newLocalName, declarationStatement, allOccurrences, cancellationToken).ConfigureAwait(false);

                case ArrowExpressionClauseSyntax arrowExpression:
                    return RewriteExpressionBodiedMemberAndIntroduceLocalDeclaration(
                        document, arrowExpression, expression, newLocalName,
                        declarationStatement, allOccurrences, cancellationToken);

                case LambdaExpressionSyntax lambda:
                    return IntroduceLocalDeclarationIntoLambda(
                        document, lambda, expression, newLocalName, declarationStatement, 
                        allOccurrences, cancellationToken);
            }

            throw new InvalidOperationException();
        }
        private Document IntroduceQueryLocalForSingleOccurrence(
            SemanticDocument document,
            ExpressionSyntax expression,
            NameSyntax newLocalName,
            LetClauseSyntax letClause,
            bool allOccurrences,
            CancellationToken cancellationToken)
        {
            var oldClause = expression.GetAncestors<SyntaxNode>().First(IsAnyQueryClause);
            var newClause = Rewrite(
                document, expression, newLocalName, document, oldClause, allOccurrences, cancellationToken);

            var oldQuery = (QueryBodySyntax)oldClause.Parent;
            var newQuery = GetNewQuery(oldQuery, oldClause, newClause, letClause);

            var newRoot = document.Root.ReplaceNode(oldQuery, newQuery);
            return document.Document.WithSyntaxRoot(newRoot);
        }
            public GeneratedCode(
                OperationStatus status,
                SemanticDocument document,
                SyntaxAnnotation methodNameAnnotation,
                SyntaxAnnotation callsiteAnnotation,
                SyntaxAnnotation methodDefinitionAnnotation)
            {
                //Contract.ThrowIfNull(document);
                //Contract.ThrowIfNull(methodNameAnnotation);
                //Contract.ThrowIfNull(callsiteAnnotation);
                //Contract.ThrowIfNull(methodDefinitionAnnotation);

                this.Status = status;
                this.SemanticDocument = document;
                this.MethodNameAnnotation = methodNameAnnotation;
                this.CallSiteAnnotation = callsiteAnnotation;
                this.MethodDefinitionAnnotation = methodDefinitionAnnotation;
            }
            public AnalyzerResult With(SemanticDocument document)
            {
                if (this.SemanticDocument == document)
                {
                    return this;
                }

                return new AnalyzerResult(
                    document,
                    _typeParametersInDeclaration,
                    _typeParametersInConstraintList,
                    _variables,
                    _variableToUseAsReturnValue,
                    this.ReturnType,
                    this.AwaitTaskReturn,
                    this.UseInstanceMember,
                    this.EndOfSelectionReachable,
                    this.Status);
            }
Пример #16
0
        public static SyntaxNode GenerateThrowStatement(
            ISyntaxFactoryService factory,
            SemanticDocument document,
            string exceptionMetadataName,
            CancellationToken cancellationToken)
        {
            var compilation = document.SemanticModel.Compilation;
            var exceptionType = compilation.GetTypeByMetadataName(exceptionMetadataName);

            // If we can't find the Exception, we obviously can't generate anything.
            if (exceptionType == null)
            {
                return null;
            }

            var exceptionCreationExpression = factory.CreateObjectCreationExpression(
                exceptionType,
                SpecializedCollections.EmptyList<SyntaxNode>());

            return factory.CreateThrowStatement(exceptionCreationExpression);
        }
        private SyntaxNode GetContainerToGenerateInto(
            SemanticDocument document, ExpressionSyntax expression, CancellationToken cancellationToken)
        {
            var anonymousMethodParameters = GetAnonymousMethodParameters(document, expression, cancellationToken);
            var lambdas = anonymousMethodParameters.SelectMany(p => p.ContainingSymbol.DeclaringSyntaxReferences.Select(r => r.GetSyntax(cancellationToken)).AsEnumerable())
                                                   .Where(n => n is ParenthesizedLambdaExpressionSyntax || n is SimpleLambdaExpressionSyntax)
                                                   .ToSet();

            var parentLambda = GetParentLambda(expression, lambdas);

            if (parentLambda != null)
            {
                return parentLambda;
            }
            else if (IsInExpressionBodiedMember(expression))
            {
                return expression.GetAncestorOrThis<ArrowExpressionClauseSyntax>();
            }
            else
            {
                return expression.GetAncestorsOrThis<BlockSyntax>().LastOrDefault();
            }
        }
 public InsertionPoint With(SemanticDocument document)
 {
     return new InsertionPoint(document, _annotation);
 }
 public SyntaxToken GetIdentifierTokenAtDeclaration(SemanticDocument document)
 {
     return document.GetTokenWithAnnotaton(_variableSymbol.IdentifierTokenAnnotation);
 }
        private async Task<Tuple<bool, OperationStatus>> TryCheckVariableTypeAsync(
            SemanticDocument document, SyntaxNode contextNode, IEnumerable<VariableInfo> variables,
            OperationStatus status, CancellationToken cancellationToken)
        {
            if (status.FailedWithNoBestEffortSuggestion())
            {
                return Tuple.Create(false, status);
            }

            var location = contextNode.GetLocation();

            foreach (var variable in variables)
            {
                var originalType = variable.GetVariableType(document);
                var result = await CheckTypeAsync(document.Document, contextNode, location, originalType, cancellationToken).ConfigureAwait(false);
                if (result.FailedWithNoBestEffortSuggestion())
                {
                    status = status.With(result);
                    return Tuple.Create(false, status);
                }
            }

            return Tuple.Create(true, status);
        }
 protected abstract Task<InsertionPoint> GetInsertionPointAsync(SemanticDocument document, int position, CancellationToken cancellationToken);
 private CSharpTriviaResult(SemanticDocument document, ITriviaSavedResult result) :
     base(document, result, (int)SyntaxKind.EndOfLineTrivia, (int)SyntaxKind.WhitespaceTrivia)
 {
 }
        private ExtractMethodResult CreateExtractMethodResult(
            OperationStatus status, SemanticDocument semanticDocument,
            SyntaxAnnotation invocationAnnotation, SyntaxAnnotation methodAnnotation)
        {
            var newRoot = semanticDocument.Root;
            var annotatedTokens = newRoot.GetAnnotatedNodesAndTokens(invocationAnnotation);
            var methodDefinition = newRoot.GetAnnotatedNodesAndTokens(methodAnnotation).FirstOrDefault().AsNode();

            return new SimpleExtractMethodResult(status, semanticDocument.Document, GetMethodNameAtInvocation(annotatedTokens), methodDefinition);
        }
        private async Task<Document> IntroduceLocalDeclarationIntoBlockAsync(
            SemanticDocument document,
            BlockSyntax block,
            ExpressionSyntax expression,
            NameSyntax newLocalName,
            LocalDeclarationStatementSyntax declarationStatement,
            bool allOccurrences,
            CancellationToken cancellationToken)
        {
            declarationStatement = declarationStatement.WithAdditionalAnnotations(Formatter.Annotation);

            var oldOutermostBlock = block;
            var matches = FindMatches(document, expression, document, oldOutermostBlock, allOccurrences, cancellationToken);
            Debug.Assert(matches.Contains(expression));

            var complexified = await ComplexifyParentingStatements(document, matches, cancellationToken).ConfigureAwait(false);
            document = complexified.Item1;
            matches = complexified.Item2;

            // 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.GetCurrentNodes(expression).First();

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

            if (innermostStatements.Count == 1)
            {
                // If there was only one match, or all the matches came from the same
                // statement, then we want to place the declaration right above that
                // statement. Note: we special case this because the statement we are going
                // to go above might not be in a block and we may have to generate it
                return IntroduceLocalForSingleOccurrenceIntoBlock(
                    document, expression, newLocalName, declarationStatement, allOccurrences, cancellationToken);
            }

            var oldInnerMostCommonBlock = matches.FindInnermostCommonBlock();
            var allAffectedStatements = new HashSet<StatementSyntax>(matches.SelectMany(expr => expr.GetAncestorsOrThis<StatementSyntax>()));
            var firstStatementAffectedInBlock = oldInnerMostCommonBlock.Statements.First(allAffectedStatements.Contains);

            var firstStatementAffectedIndex = oldInnerMostCommonBlock.Statements.IndexOf(firstStatementAffectedInBlock);

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

            var statements = new List<StatementSyntax>();
            statements.AddRange(newInnerMostBlock.Statements.Take(firstStatementAffectedIndex));
            statements.Add(declarationStatement);
            statements.AddRange(newInnerMostBlock.Statements.Skip(firstStatementAffectedIndex));

            var finalInnerMostBlock = newInnerMostBlock.WithStatements(
                SyntaxFactory.List<StatementSyntax>(statements));

            var newRoot = document.Root.ReplaceNode(oldInnerMostCommonBlock, finalInnerMostBlock);
            return document.Document.WithSyntaxRoot(newRoot);
        }
        private Document IntroduceLocalForSingleOccurrenceIntoBlock(
            SemanticDocument document,
            ExpressionSyntax expression,
            NameSyntax localName,
            LocalDeclarationStatementSyntax localDeclaration,
            bool allOccurrences,
            CancellationToken cancellationToken)
        {
            var oldStatement = expression.GetAncestorOrThis<StatementSyntax>();
            var newStatement = Rewrite(
                document, expression, localName, document, oldStatement, allOccurrences, cancellationToken);

            if (oldStatement.IsParentKind(SyntaxKind.Block))
            {
                var oldBlock = oldStatement.Parent as BlockSyntax;
                var statementIndex = oldBlock.Statements.IndexOf(oldStatement);

                var newBlock = oldBlock.WithStatements(CreateNewStatementList(
                    oldBlock.Statements, localDeclaration, newStatement, statementIndex));

                var newRoot = document.Root.ReplaceNode(oldBlock, newBlock);
                return document.Document.WithSyntaxRoot(newRoot);
            }
            else if (oldStatement.IsParentKind(SyntaxKind.SwitchSection))
            {
                var oldSwitchSection = oldStatement.Parent as SwitchSectionSyntax;
                var statementIndex = oldSwitchSection.Statements.IndexOf(oldStatement);

                var newSwitchSection = oldSwitchSection.WithStatements(CreateNewStatementList(
                    oldSwitchSection.Statements, localDeclaration, newStatement, statementIndex));

                var newRoot = document.Root.ReplaceNode(oldSwitchSection, newSwitchSection);
                return document.Document.WithSyntaxRoot(newRoot);
            }
            else
            {
                // we need to introduce a block to put the original statement, along with
                // the statement we're generating
                var newBlock = SyntaxFactory.Block(localDeclaration, newStatement).WithAdditionalAnnotations(Formatter.Annotation);

                var newRoot = document.Root.ReplaceNode(oldStatement, newBlock);
                return document.Document.WithSyntaxRoot(newRoot);
            }
        }
		private TypeSyntax GetTypeSyntax(SemanticDocument document, ExpressionSyntax expression, bool isConstant, OptionSet options, CancellationToken cancellationToken)
		{
			var typeSymbol = GetTypeSymbol(document, expression, cancellationToken);
			if (typeSymbol.ContainsAnonymousType())
			{
				return SyntaxFactory.IdentifierName("var");
			}

			if (!isConstant && true /*options.GetOption(CSharpCodeStyleOptions.UseVarWhenDeclaringLocals) */&& CanUseVar(typeSymbol))
			{
				return SyntaxFactory.IdentifierName("var");
			}

			return typeSymbol.GenerateTypeSyntax();
		}
        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)
            {
                var getAccessor = SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration, newBody);
                var accessorList = SyntaxFactory.AccessorList(SyntaxFactory.List(new[] { getAccessor }));

                newParentingNode = ((BasePropertyDeclarationSyntax)oldParentingNode).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)
            {
                newParentingNode = ((BaseMethodDeclarationSyntax)oldParentingNode)
                    .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);
        }
        private static async Task<Tuple<SemanticDocument, ISet<ExpressionSyntax>>> ComplexifyParentingStatements(
            SemanticDocument semanticDocument,
            ISet<ExpressionSyntax> matches,
            CancellationToken cancellationToken)
        {
            // First, track the matches so that we can get back to them later.
            var newRoot = semanticDocument.Root.TrackNodes(matches);
            var newDocument = semanticDocument.Document.WithSyntaxRoot(newRoot);
            var newSemanticDocument = await SemanticDocument.CreateAsync(newDocument, cancellationToken).ConfigureAwait(false);
            var newMatches = newSemanticDocument.Root.GetCurrentNodes(matches.AsEnumerable()).ToSet();

            // Next, expand the topmost parenting expression of each match, being careful
            // not to expand the matches themselves.
            var topMostExpressions = newMatches
                .Select(m => m.AncestorsAndSelf().OfType<ExpressionSyntax>().Last())
                .Distinct();

            newRoot = await newSemanticDocument.Root
                .ReplaceNodesAsync(
                    topMostExpressions,
                    computeReplacementAsync: async (oldNode, newNode, ct) =>
                    {
                        return await Simplifier
                            .ExpandAsync(
                                oldNode,
                                newSemanticDocument.Document,
                                expandInsideNode: node =>
                                {
                                    var expression = node as ExpressionSyntax;
                                    return expression == null
                                        || !newMatches.Contains(expression);
                                },
                                cancellationToken: ct)
                            .ConfigureAwait(false);
                    },
                    cancellationToken: cancellationToken)
                .ConfigureAwait(false);

            newDocument = newSemanticDocument.Document.WithSyntaxRoot(newRoot);
            newSemanticDocument = await SemanticDocument.CreateAsync(newDocument, cancellationToken).ConfigureAwait(false);
            newMatches = newSemanticDocument.Root.GetCurrentNodes(matches.AsEnumerable()).ToSet();

            return Tuple.Create(newSemanticDocument, newMatches);
        }
        private TypeSyntax GetTypeSyntax(SemanticDocument document, DocumentOptionSet options, ExpressionSyntax expression, bool isConstant, CancellationToken cancellationToken)
        {
            var typeSymbol = GetTypeSymbol(document, expression, cancellationToken);
            if (typeSymbol.ContainsAnonymousType())
            {
                return SyntaxFactory.IdentifierName("var");
            }

            if (!isConstant && 
                CanUseVar(typeSymbol) && 
                TypeStyleHelper.IsImplicitTypePreferred(expression, document.SemanticModel, options, cancellationToken))
            {
                return SyntaxFactory.IdentifierName("var");
            }

            return typeSymbol.GenerateTypeSyntax();
        }
 public ITypeSymbol GetVariableType(SemanticDocument document)
 {
     return document.SemanticModel.ResolveType(_variableSymbol.OriginalType);
 }