private ArgumentSyntax generateRunTaskWrapper(BlockSyntax blocks, params ParameterSyntax[] parameters)
		{
			return Argument(taskBuilder
					.ParenthesizedLambdaExpression(blocks)
					.AddParameterListParameters(parameters)
				);
		}
		public override void VisitBlock(BlockSyntax node)
		{
			if (_firstVisit)
			{
				_firstVisit = false;
				foreach (var statement in node.Statements)
				{
					var leadingTabs = new string('\t', 3 + ClassDepth);
					SyntaxNode formattedStatement = statement;

					_code = formattedStatement.WithoutLeadingTrivia().WithTrailingTrivia().ToFullString().Replace(leadingTabs, string.Empty);

					var nodeLine = formattedStatement.SyntaxTree.GetLineSpan(node.Span).StartLinePosition.Line;

					var line = _lineNumberOverride ?? nodeLine;

					var codeBlocks = Regex.Split(_code, @"\/\*\*.*?\*\/", RegexOptions.Singleline)
						.Select(b => b.TrimStart('\r', '\n').TrimEnd('\r', '\n', '\t'))
						.Where(b => !string.IsNullOrEmpty(b) && b != ";")
						.Select(b => new CodeBlock(b, line))
						.ToList();

					this.Blocks.AddRange(codeBlocks);
				}

				base.Visit(node);
			}
		}
 public static BaseMethodDeclarationSyntax WithBody(this BaseMethodDeclarationSyntax item, BlockSyntax body)
 {
     var cons = item as ConstructorDeclarationSyntax;
     if (cons != null)
     {
         return cons.WithBody(body);
     }
     var conv = item as ConversionOperatorDeclarationSyntax;
     if (conv != null)
     {
         return conv.WithBody(body);
     }
     var dest = item as DestructorDeclarationSyntax;
     if (dest != null)
     {
         return dest.WithBody(body);
     }
     var meth = item as MethodDeclarationSyntax;
     if (meth != null)
     {
         return meth.WithBody(body);
     }
     var oper = item as OperatorDeclarationSyntax;
     if (oper != null)
     {
         return oper.WithBody(body);
     }
     throw new ArgumentException("Unknown " + typeof(BaseMethodDeclarationSyntax).FullName, "item");
 }
            private IEnumerable<StatementSyntax> RemoveRedundantBlock(BlockSyntax block)
            {
                // if block doesn't have any statement
                if (block.Statements.Count == 0)
                {
                    // either remove the block if it doesn't have any trivia, or return as it is if
                    // there are trivia attached to block
                    return (block.OpenBraceToken.GetAllTrivia().IsEmpty() && block.CloseBraceToken.GetAllTrivia().IsEmpty()) ?
                        SpecializedCollections.EmptyEnumerable<StatementSyntax>() : SpecializedCollections.SingletonEnumerable<StatementSyntax>(block);
                }

                // okay transfer asset attached to block to statements
                var firstStatement = block.Statements.First();
                var firstToken = firstStatement.GetFirstToken(includeZeroWidth: true);
                var firstTokenWithAsset = block.OpenBraceToken.CopyAnnotationsTo(firstToken).WithPrependedLeadingTrivia(block.OpenBraceToken.GetAllTrivia());

                var lastStatement = block.Statements.Last();
                var lastToken = lastStatement.GetLastToken(includeZeroWidth: true);
                var lastTokenWithAsset = block.CloseBraceToken.CopyAnnotationsTo(lastToken).WithAppendedTrailingTrivia(block.CloseBraceToken.GetAllTrivia());

                // create new block with new tokens
                block = block.ReplaceTokens(new[] { firstToken, lastToken }, (o, c) => (o == firstToken) ? firstTokenWithAsset : lastTokenWithAsset);

                // return only statements without the wrapping block
                return block.Statements;
            }
 public static MethodDeclarationSyntax MethodDeclaration(
     SyntaxList<AttributeListSyntax> attributeLists,
     SyntaxTokenList modifiers,
     TypeSyntax returnType,
     ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier,
     SyntaxToken identifier,
     TypeParameterListSyntax typeParameterList,
     ParameterListSyntax parameterList,
     SyntaxList<TypeParameterConstraintClauseSyntax> constraintClauses,
     BlockSyntax body,
     SyntaxToken semicolonToken)
 {
     return SyntaxFactory.MethodDeclaration(
         attributeLists,
         modifiers,
         default(SyntaxToken),
         returnType,
         explicitInterfaceSpecifier,
         identifier,
         typeParameterList,
         parameterList,
         constraintClauses,
         body,
         default(ArrowExpressionClauseSyntax),
         semicolonToken);
 }
示例#6
0
        private bool GetSpeculativeSemanticModelForMethodBody(SyntaxTreeSemanticModel parentModel, int position, BlockSyntax body, out SemanticModel speculativeModel)
        {
            position = CheckAndAdjustPosition(position);

            var methodSymbol = (MethodSymbol)this.MemberSymbol;

            // Strip off ExecutableCodeBinder (see ctor).
            Binder binder = this.RootBinder;

            do
            {
                if (binder is ExecutableCodeBinder)
                {
                    binder = binder.Next;
                    break;
                }

                binder = binder.Next;
            }
            while (binder != null);

            Debug.Assert(binder != null);

            var executablebinder = new ExecutableCodeBinder(body, methodSymbol, binder ?? this.RootBinder);
            var blockBinder = executablebinder.GetBinder(body).WithAdditionalFlags(GetSemanticModelBinderFlags());
            speculativeModel = CreateSpeculative(parentModel, methodSymbol, body, blockBinder, position);
            return true;
        }
            public override SyntaxNode VisitBlock(BlockSyntax node)
            {
                BlockSyntax block = (BlockSyntax)base.VisitBlock(node);
                SyntaxList<StatementSyntax> curList = new SyntaxList<StatementSyntax>();
                Dictionary<string, SyntaxNode> replacements = new Dictionary<string, SyntaxNode>();

                int numbering = 1;
                foreach (var stmt in block.Statements)
                {
                    SyntaxList<StatementSyntax> preList = new SyntaxList<StatementSyntax>();
                    var stm = stmt.ReplaceNodes(nodes: stmt.DescendantNodes().Reverse(), computeReplacementNode: (original, origWithReplacedDesc) =>
                    {
                        Console.WriteLine(origWithReplacedDesc.GetType() + ": " + origWithReplacedDesc);

                        if (origWithReplacedDesc.IsKind(SyntaxKind.InvocationExpression)
                            || origWithReplacedDesc.IsKind(SyntaxKind.ObjectCreationExpression))
                        {
                            return SimplifyMethodAndConstructorInvocation(ref numbering, ref preList, original, origWithReplacedDesc);
                        }
                        return origWithReplacedDesc;
                    });
                    curList = curList.AddRange(preList);
                    curList = curList.Add(stm);
                }
                return block.WithStatements(curList);
            }
示例#8
0
 public override void VisitBlock(BlockSyntax node)
 {
     foreach (var statement in node.Statements)
     {
         base.Visit(statement);
     }
 }
示例#9
0
        public override SyntaxNode VisitBlock(BlockSyntax node)
        {
            var results = base.VisitBlock (node);
            if ((node = results as BlockSyntax) == null)
                return results;

            var list = new List<StatementSyntax>();
            foreach (StatementSyntax statement in node.Statements)
            {
                var s = statement;

                bool isloop = s.GetIsLoop();
                if (isloop)
                    s = s.WithLeadingTrivia (s.GetLeadingTrivia().InsertComment (GetIdComment (this.blockIds.Dequeue())));

                if (this.loopLevel > 0)
                {
                    if (s is ContinueStatementSyntax || s is BreakStatementSyntax || s is ReturnStatementSyntax)
                        s = s.WithTrailingTrivia (s.GetTrailingTrivia().Prepend (GetIdComment()));
                    if (s is ReturnStatementSyntax && ((ReturnStatementSyntax)s).Expression == null)
                        s = s.WithTrailingTrivia (s.GetTrailingTrivia().Prepend (GetIdComment()));
                }

                list.Add (s);

                if (isloop)
                    s = s.WithTrailingTrivia (s.GetTrailingTrivia().Prepend (GetIdComment()));
            }

            return node.WithStatements (Syntax.List<StatementSyntax> (list));
        }
        internal static BoundStatement AddSequencePoint(BlockSyntax blockSyntax, BoundStatement rewrittenStatement, bool isPrimaryCtor)
        {
            TextSpan span;

            if (isPrimaryCtor)
            {
                // For a primary constructor block: ... [|{|] ... }
                return new BoundSequencePointWithSpan(blockSyntax, rewrittenStatement, blockSyntax.OpenBraceToken.Span);
            }

            var parent = blockSyntax.Parent as ConstructorDeclarationSyntax;
            if (parent != null)
            {
                span = CreateSpanForConstructorDeclaration(parent);
            }
            else
            {
                // This inserts a sequence points to any prologue code for method declarations.
                var start = blockSyntax.Parent.SpanStart;
                var end = blockSyntax.OpenBraceToken.GetPreviousToken().Span.End;
                span = TextSpan.FromBounds(start, end);
            }

            return new BoundSequencePointWithSpan(blockSyntax, rewrittenStatement, span);
        }
示例#11
0
		public ParenthesizedLambdaExpressionSyntax ParenthesizedLambdaExpression(BlockSyntax blocks)
		{
			return SF.ParenthesizedLambdaExpression(
						Block(
							ReturnStatement(
								InvocationExpression(
									Extensions.MemberAccess(
										InvocationExpression(
											Extensions.MemberAccess(
												IdentifierName("Task"),
												IdentifierName("Run")
											)
										).AddArgumentListArguments(
											Argument(
												SF.ParenthesizedLambdaExpression(
													blocks
												)
											)
										),
										IdentifierName("AsAsyncOperation")
									)
							).AddArgumentListArguments()
						)
					)
				);
		}
		private IEnumerable<string> Inspect(BlockSyntax block)
		{
			var startLine = GetSpan(block.OpenBraceToken).StartLinePosition.Line;
			var endLine = GetSpan(block.CloseBraceToken).EndLinePosition.Line;
			if (endLine - startLine >= maxLen)
				yield return Report(block.OpenBraceToken, "Слишком длинный блок инструкций. Попытайтесь разбить его на вспомогательные методы");
		}
        private static SyntaxNode ReformatBlockAndParent(Document document, SyntaxNode syntaxRoot, BlockSyntax block)
        {
            var parentLastToken = block.OpenBraceToken.GetPreviousToken();

            var parentEndLine = parentLastToken.GetEndLine();
            var blockStartLine = block.OpenBraceToken.GetLine();

            var newParentLastToken = parentLastToken;
            if (parentEndLine == blockStartLine)
            {
                var newTrailingTrivia = parentLastToken.TrailingTrivia
                    .WithoutTrailingWhitespace()
                    .Add(SyntaxFactory.CarriageReturnLineFeed);

                newParentLastToken = newParentLastToken.WithTrailingTrivia(newTrailingTrivia);
            }

            var parentNextToken = block.CloseBraceToken.GetNextToken();

            var nextTokenLine = parentNextToken.GetLine();
            var blockCloseLine = block.CloseBraceToken.GetEndLine();

            var newParentNextToken = parentNextToken;
            if (nextTokenLine == blockCloseLine)
            {
                newParentNextToken = newParentNextToken.WithLeadingTrivia(parentLastToken.LeadingTrivia);
            }

            var newBlock = ReformatBlock(document, block);
            var rewriter = new BlockRewriter(parentLastToken, newParentLastToken, block, newBlock, parentNextToken, newParentNextToken);

            var newSyntaxRoot = rewriter.Visit(syntaxRoot);
            return newSyntaxRoot.WithoutFormatting();
        }
示例#14
0
        private static string Block(BlockSyntax node, bool braces = true)
        {
            var output = (braces ? "{" + NewLine : "");

            output += string.Join("", node.ChildNodes().Select(SyntaxNode));

            return output + (braces ? "}" + NewLine + NewLine : "");
        }
示例#15
0
        public static BlockSyntax AddTrailingBlankLine(BlockSyntax block)
        {
            Debug.Assert(block != null && NeedsTrailingBlankLine(block));

            return block
                .WithTrailingTrivia(block.GetTrailingTrivia().Add(SyntaxFactory.CarriageReturnLineFeed))
                .WithAdditionalAnnotations(Formatter.Annotation);
        }
示例#16
0
 protected override SyntaxNode VisitBlock(BlockSyntax node)
 {
     // If we have an unbreakable node, replace it with a try-catch expression (using the current node as the try block)
     if (node == _blockToProtect)
     {
         return Syntax.TryStatement(block: node, catches: Syntax.CatchClause(block: Syntax.Block()));
     }
     return base.VisitBlock(node);
 }
        public override SyntaxNode VisitBlock(BlockSyntax node)
        {
            if (node.Statements.Count > 2)
            {
                node = node.WithAdditionalAnnotations(LayoutAnnotations.MultiLineConstructAnnotation);
            }

            return base.VisitBlock(node);
        }
示例#18
0
 public override void VisitBlock(BlockSyntax node)
 {
     var oldIsInScope = isInScope;
     if (!contextParents.Contains(node))
         isInScope = false;
     base.VisitBlock(node);
     if (!isInScope && oldIsInScope)
         isInScope = true;
 }
示例#19
0
            public override void VisitBlock(BlockSyntax node)
            {
                var statements = node.ChildNodes().OfType<ExpressionStatementSyntax>();
                var invocations = statements.Select(s => s.Expression).OfType<InvocationExpressionSyntax>();
                var glOperators = invocations.Select(i => i.Expression).OfType<MemberAccessExpressionSyntax>()
                    .Where(m => m.IsKind(SyntaxKind.SimpleMemberAccessExpression)).Where(s => s.GetFirstToken().Text == nameof(GL));
                var beginEnds = glOperators.Select(g => Tuple.Create(g.Parent as InvocationExpressionSyntax, g.ChildNodes().Skip(1).FirstOrDefault()?.GetFirstToken().Text))
                    .Where(p => p.Item2 == nameof(GL.Begin) || p.Item2 == nameof(GL.End));

                // filtering
                if (!beginEnds.Any())
                {
                    base.VisitBlock(node);
                    return;
                }

                // block contains GL.Begin() or GL.End()
                var counter = 0;
                Location prevBeginLocation = null;
                foreach (var pair in beginEnds)
                {
                    if (pair.Item2 == nameof(GL.Begin))
                    {
                        counter++;
                        if (counter > 1)
                        {
                            Diagnostics.Add(Diagnostic.Create(
                                descriptor: Rule,
                                location: prevBeginLocation,
                                messageArgs: nameof(GL) + "." + nameof(GL.End)));
                            counter = 1;
                        }
                        prevBeginLocation = pair.Item1.GetLocation();
                    }
                    else if (pair.Item2 == nameof(GL.End))
                    {
                        counter--;
                        if (counter < 0)
                        {
                            Diagnostics.Add(Diagnostic.Create(
                                descriptor: Rule,
                                location: pair.Item1.GetLocation(),
                                messageArgs: nameof(GL) + "." + nameof(GL.Begin)));
                            counter = 0;
                        }
                    }
                }
                if (counter > 0)
                {
                    Diagnostics.Add(Diagnostic.Create(
                        descriptor: Rule,
                        location: prevBeginLocation,
                        messageArgs: nameof(GL) + "." + nameof(GL.End)));
                }

                base.VisitBlock(node);
            }
示例#20
0
        public static AccessorDeclarationSyntax AccessorDeclaration(AccessorDeclarationKind kind = default(AccessorDeclarationKind), BlockSyntax body = null)
        {
            var result = new AccessorDeclarationSyntax();

            result.Kind = kind;
            result.Body = body;

            return result;
        }
        public override void VisitBlock(BlockSyntax node)
        {
            foreach (StatementSyntax statement in node.Statements)
            {
                CreateAuditVariable(statement);
            }

            base.VisitBlock(node);
        }
示例#22
0
        private bool GetSpeculativeSemanticModelForMethodBody(SyntaxTreeSemanticModel parentModel, int position, BlockSyntax body, out SemanticModel speculativeModel)
        {
            position = CheckAndAdjustPosition(position);

            var methodSymbol = (MethodSymbol)this.MemberSymbol;
            var executablebinder = new ExecutableCodeBinder(body, methodSymbol, this.rootBinder.Next); // Strip off ExecutableCodeBinder (see ctor).
            var blockBinder = executablebinder.GetBinder(body).WithAdditionalFlags(BinderFlags.SemanticModel);
            speculativeModel = CreateSpeculative(parentModel, methodSymbol, body, blockBinder, position);
            return true;
        }
示例#23
0
		public MethodDeclarationSyntax AsyncMethod(TypeArgumentListSyntax list, string name, BlockSyntax body)
		{
			var amethod = ParenthesizedLambdaExpression(body)
				.WithAsyncKeyword(Token(SyntaxKind.AsyncKeyword));

			return MethodDeclaration(
				GenericName(Identifier("Task"))
				.WithTypeArgumentList(list),
				Identifier(name)
				).WithBody(body).AddModifiers(Token(SyntaxKind.AsyncKeyword));
		}
 public Rewriter(
     BlockSyntax oldInnermostBlock,
     BlockSyntax newInnermostBlock,
     BlockSyntax oldOutermostBlock,
     LocalDeclarationStatementSyntax declarationStatement)
 {
     _oldInnermostBlock = oldInnermostBlock;
     _newInnermostBlock = newInnermostBlock;
     _oldOutermostBlock = oldOutermostBlock;
     _declarationStatement = declarationStatement;
 }
示例#25
0
        public SwitchCase(ExpressionSyntax expression, BlockSyntax body, SourceLocation location)
        {
            if (body == null)
                throw new ArgumentNullException("body");
            if (location == null)
                throw new ArgumentNullException("location");

            Expression = expression;
            Body = body;
            Location = location;
        }
示例#26
0
        public static AccessorDeclarationSyntax AccessorDeclaration(AccessorDeclarationKind kind = default(AccessorDeclarationKind), IEnumerable<AttributeListSyntax> attributeLists = null, Modifiers modifiers = default(Modifiers), BlockSyntax body = null)
        {
            var result = new AccessorDeclarationSyntax();

            result.Kind = kind;
            if (attributeLists != null)
                result.AttributeLists.AddRange(attributeLists);
            result.Modifiers = modifiers;
            result.Body = body;

            return result;
        }
示例#27
0
		public void VisitBlock(BlockSyntax node)
		{
			var tokens = node.DescendantTokens().ToList();
			var dictionary = ParseTokens(tokens, Operands.All);
			var dictionary2 = ParseTokens(tokens, Operators.All);
			var metrics = new HalsteadMetrics(
				numOperands: dictionary.Values.Sum(x => x.Count), 
				numUniqueOperands: dictionary.Values.SelectMany(x => x).Distinct().Count(), 
				numOperators: dictionary2.Values.Sum(x => x.Count), 
				numUniqueOperators: dictionary2.Values.SelectMany(x => x).Distinct().Count());
			_metrics = metrics;
		}
示例#28
0
 public override SyntaxNode VisitBlock(BlockSyntax node)
 {
     if (_isSaveChanges && node.Parent is UsingStatementSyntax && node.Statements.Count > 2)
     {
         _isSaveChanges = false;
         return node.WithStatements(
             SyntaxFactory.List(
                 node.Statements.Take(node.Statements.Count - 2)
                     .Union(new[] { SyntaxFactory.ParseStatement(_edmxName + "SaveChanges(clientContexts);") })
                     .Union(node.Statements.Skip(node.Statements.Count - 2))));
     }
     return base.VisitBlock(node);
 }
 public override SyntaxNode VisitBlock(BlockSyntax node)
 {
     if (_initWAQSModules)
     {
         var statements = new[] { string.Format("            unityContainer.RegisterType<I{0}Service, {0}ServiceClient>(new InjectionConstructor());\r\n", _edmxName), string.Format("            unityContainer.RegisterType<I{0}ClientContext, {0}ClientContext>();\r\n", _edmxName) };
         var value = node.WithStatements(
             SyntaxFactory.List(
                 statements.Select(s => SyntaxFactory.ParseStatement(s)).Union(node.Statements)));
         _initWAQSModules = false;
         return value;
     }
     return base.VisitBlock(node);
 }
        static bool HasNotNullContract(SemanticModel semanticModel, IParameterSymbol parameterSymbol, BlockSyntax bodyStatement)
        {
            foreach (var expressions in bodyStatement.DescendantNodes().OfType<ExpressionStatementSyntax>())
            {
                var identifiers = expressions.DescendantNodes().OfType<IdentifierNameSyntax>();

                if (Enumerable.SequenceEqual(identifiers.Select(i => i.Identifier.Text), new List<string>() { "Contract", "Requires", parameterSymbol.Name }))
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// Visits the syntax node.
        /// </summary>
        internal void Visit(StateDeclaration parentNode)
        {
            this.TokenStream.Index++;
            this.TokenStream.SkipWhiteSpaceAndCommentTokens();

            if (this.TokenStream.Done ||
                (this.TokenStream.Peek().Type != TokenType.Identifier &&
                 this.TokenStream.Peek().Type != TokenType.MulOp &&
                 this.TokenStream.Peek().Type != TokenType.HaltEvent &&
                 this.TokenStream.Peek().Type != TokenType.DefaultEvent))
            {
                throw new ParsingException("Expected event identifier.", this.TokenStream.Peek(),
                                           TokenType.Identifier,
                                           TokenType.HaltEvent,
                                           TokenType.DefaultEvent);
            }

            var nameVisitor = new NameVisitor(this.TokenStream);

            // Consumes multiple generic event names.
            var eventIdentifiers = nameVisitor.ConsumeMultipleNames(TokenType.EventIdentifier, tt => nameVisitor.ConsumeGenericEventName(tt));

            if (!this.TokenStream.Done &&
                this.TokenStream.Peek().Type == TokenType.Identifier)
            {
                throw new ParsingException("Expected \",\".", this.TokenStream.Peek(), TokenType.Comma);
            }

            if (!this.TokenStream.Done &&
                (this.TokenStream.Peek().Type == TokenType.LeftAngleBracket ||
                 this.TokenStream.Peek().Type == TokenType.RightAngleBracket))
            {
                throw new ParsingException("Invalid generic expression.", this.TokenStream.Peek());
            }

            if (this.TokenStream.Done ||
                (this.TokenStream.Peek().Type != TokenType.DoAction &&
                 this.TokenStream.Peek().Type != TokenType.GotoState &&
                 this.TokenStream.Peek().Type != TokenType.PushState))
            {
                throw new ParsingException("Expected \"do\", \"goto\" or \"push\".", this.TokenStream.Peek(),
                                           TokenType.DoAction,
                                           TokenType.GotoState,
                                           TokenType.PushState);
            }

            var resolvedEventIdentifiers = new Dictionary <Token, List <Token> >();

            foreach (var eventIdentifier in eventIdentifiers)
            {
                if (eventIdentifier.Count == 1)
                {
                    // We don't want to collapse halt and default
                    // events to event identifiers.
                    resolvedEventIdentifiers.Add(eventIdentifier[0], eventIdentifier);
                }
                else
                {
                    var identifierBuilder = new StringBuilder();
                    foreach (var token in eventIdentifier)
                    {
                        identifierBuilder.Append(token.TextUnit.Text);
                    }

                    TextUnit textUnit = new TextUnit(identifierBuilder.ToString(), eventIdentifier[0].TextUnit);
                    resolvedEventIdentifiers.Add(new Token(textUnit, TokenType.EventIdentifier), eventIdentifier);
                }
            }

            if (this.TokenStream.Peek().Type == TokenType.DoAction)
            {
                this.TokenStream.Index++;
                this.TokenStream.SkipWhiteSpaceAndCommentTokens();

                bool isAsync = false;

                if (!this.TokenStream.Done)
                {
                    if (this.TokenStream.Peek().Type == TokenType.Async)
                    {
                        isAsync = true;
                        this.TokenStream.Index++;
                        this.TokenStream.SkipWhiteSpaceAndCommentTokens();
                    }

                    if (this.TokenStream.Peek().Type == TokenType.Await)
                    {
                        throw new ParsingException("'await' should not be used on actions.", this.TokenStream.Peek());
                    }
                }

                if (this.TokenStream.Done ||
                    (this.TokenStream.Peek().Type != TokenType.Identifier &&
                     this.TokenStream.Peek().Type != TokenType.LeftCurlyBracket))
                {
                    var message = isAsync
                        ? "Expected action identifier or opening curly bracket."
                        : "Expected async keyword, action identifier, or opening curly bracket.";
                    if (!isAsync)
                    {
                        throw new ParsingException(message, this.TokenStream.Peek(), TokenType.Async, TokenType.Identifier, TokenType.LeftCurlyBracket);
                    }
                    else
                    {
                        throw new ParsingException(message, this.TokenStream.Peek(), TokenType.Identifier, TokenType.LeftCurlyBracket);
                    }
                }

                if (this.TokenStream.Peek().Type == TokenType.LeftCurlyBracket)
                {
                    var blockNode = new BlockSyntax(this.TokenStream.Program, parentNode.Machine, null);
                    new BlockSyntaxVisitor(this.TokenStream).Visit(blockNode);

                    foreach (var kvp in resolvedEventIdentifiers)
                    {
                        if (!parentNode.AddActionBinding(kvp.Key, kvp.Value, new AnonymousActionHandler(blockNode, isAsync)))
                        {
                            throw new ParsingException("Unexpected action handler.", this.TokenStream.Peek());
                        }
                    }
                }
                else
                {
                    if (isAsync)
                    {
                        throw new ParsingException("'async' should only be used on anonymous actions.", this.TokenStream.Peek());
                    }

                    this.TokenStream.Swap(TokenType.ActionIdentifier);

                    var actionIdentifier = this.TokenStream.Peek();
                    foreach (var kvp in resolvedEventIdentifiers)
                    {
                        if (!parentNode.AddActionBinding(kvp.Key, kvp.Value, actionIdentifier))
                        {
                            throw new ParsingException("Unexpected action handler.", this.TokenStream.Peek());
                        }
                    }

                    this.TokenStream.Index++;
                    this.TokenStream.SkipWhiteSpaceAndCommentTokens();

                    if (this.TokenStream.Done ||
                        this.TokenStream.Peek().Type != TokenType.Semicolon)
                    {
                        throw new ParsingException("Expected \";\".", this.TokenStream.Peek(), TokenType.Semicolon);
                    }
                }
            }
            else if (this.TokenStream.Peek().Type == TokenType.GotoState)
            {
                var stateIdentifiers = this.ConsumeState();

                if (this.TokenStream.Done ||
                    (this.TokenStream.Peek().Type != TokenType.WithExit &&
                     this.TokenStream.Peek().Type != TokenType.Semicolon))
                {
                    throw new ParsingException("Expected \";\".", this.TokenStream.Peek(), TokenType.Semicolon);
                }

                if (this.TokenStream.Peek().Type == TokenType.WithExit)
                {
                    this.TokenStream.Index++;
                    this.TokenStream.SkipWhiteSpaceAndCommentTokens();

                    bool isAsync = false;
                    if (this.TokenStream.Peek().Type == TokenType.Async)
                    {
                        isAsync = true;
                        this.TokenStream.Index++;
                        this.TokenStream.SkipWhiteSpaceAndCommentTokens();
                    }

                    if (this.TokenStream.Done ||
                        this.TokenStream.Peek().Type != TokenType.LeftCurlyBracket)
                    {
                        throw new ParsingException("Expected \"{\".", this.TokenStream.Peek(), TokenType.LeftCurlyBracket);
                    }

                    var blockNode = new BlockSyntax(this.TokenStream.Program, parentNode.Machine, null);
                    new BlockSyntaxVisitor(this.TokenStream).Visit(blockNode);

                    foreach (var kvp in resolvedEventIdentifiers)
                    {
                        if (!parentNode.AddGotoStateTransition(kvp.Key, kvp.Value, stateIdentifiers,
                                                               new AnonymousActionHandler(blockNode, isAsync)))
                        {
                            throw new ParsingException("Unexpected goto state transition.", this.TokenStream.Peek());
                        }
                    }
                }
                else
                {
                    foreach (var kvp in resolvedEventIdentifiers)
                    {
                        if (!parentNode.AddGotoStateTransition(kvp.Key, kvp.Value, stateIdentifiers))
                        {
                            throw new ParsingException("Unexpected goto state transition.", this.TokenStream.Peek());
                        }
                    }
                }
            }
            else if (this.TokenStream.Peek().Type == TokenType.PushState)
            {
                if (parentNode.Machine.IsMonitor)
                {
                    throw new ParsingException("Monitors cannot \"push\".", this.TokenStream.Peek());
                }

                var stateIdentifiers = this.ConsumeState();

                if (this.TokenStream.Done ||
                    this.TokenStream.Peek().Type != TokenType.Semicolon)
                {
                    throw new ParsingException("Expected \";\".", this.TokenStream.Peek(), TokenType.Semicolon);
                }

                foreach (var kvp in resolvedEventIdentifiers)
                {
                    if (!parentNode.AddPushStateTransition(kvp.Key, kvp.Value, stateIdentifiers))
                    {
                        throw new ParsingException("Unexpected push state transition.", this.TokenStream.Peek());
                    }
                }
            }
        }
示例#32
0
        private static SyntaxList <StatementSyntax> InsertLocalVariableDeclarationBeforeCallSite(BlockSyntax block, VariableDeclarationSyntax varDecl, ExpressionSyntax callSite)
        {
            var stmts = block.Statements;

            var callSiteStatement = callSite.Ancestors().First(node => node.Parent.Kind() == SyntaxKind.Block);

            var i = stmts.IndexOf(stmt => stmt.IsEquivalentTo(callSiteStatement));

            var newStmts = stmts.Insert(i, SyntaxFactory.LocalDeclarationStatement(varDecl).WithNewLine());

            return(SyntaxFactory.List(newStmts.AsEnumerable()));
        }
示例#33
0
        public SyntaxNode Replace(SyntaxNode root, SemanticModel model)
        {
            var switches = root.DescendantNodes().OfType <SwitchStatementSyntax>().Where(sw => {
                return(sw.Sections.Any(s => s.Labels.Any(l => l is CasePatternSwitchLabelSyntax)));
            });

            var tempKey = 0;

            root = root.ReplaceNodes(switches, (s1, sw) =>
            {
                var ifNodes = new List <IfStatementSyntax>();
                BlockSyntax defaultBlock = null;
                var isComplex            = IsExpressionComplexEnoughToGetATemporaryVariable.IsComplex(model, s1.Expression);
                var switchExpression     = sw.Expression;
                StatementSyntax switchConditionVariable = null;

                var iType          = model.GetTypeInfo(s1.Expression).Type;
                var expressionType = SyntaxFactory.ParseTypeName(iType.ToMinimalDisplayString(model, s1.Expression.GetLocation().SourceSpan.Start));

                if (isComplex)
                {
                    var key              = tempKey++;
                    var keyArg           = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal("case_pattern" + key));
                    var methodIdentifier = SyntaxFactory.IdentifierName("global::Bridge.Script.ToTemp");

                    var toTemp = SyntaxFactory.InvocationExpression(methodIdentifier,
                                                                    SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(keyArg), SyntaxFactory.Argument(switchExpression) })));

                    switchConditionVariable = SyntaxFactory.ExpressionStatement(toTemp).NormalizeWhitespace();

                    var parentMethodIdentifier = SyntaxFactory.GenericName(SyntaxFactory.Identifier("global::Bridge.Script.FromTemp"),
                                                                           SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(new[] { expressionType })));
                    switchExpression = SyntaxFactory.InvocationExpression(parentMethodIdentifier,
                                                                          SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(keyArg) })));
                }

                foreach (var section in sw.Sections)
                {
                    var tuple     = CollectCondition(switchExpression, section.Labels, expressionType);
                    var condition = tuple.Item1;
                    var variables = tuple.Item2;
                    var whens     = tuple.Item3;

                    var body     = SyntaxFactory.Block();
                    var whenBody = SyntaxFactory.Block();

                    foreach (var variable in variables)
                    {
                        body = body.WithStatements(body.Statements.Add(SyntaxFactory.LocalDeclarationStatement(variable)));
                    }

                    foreach (var statement in section.Statements)
                    {
                        if (whens.Count > 0)
                        {
                            whenBody = whenBody.WithStatements(whenBody.Statements.Add(statement));
                        }
                        else
                        {
                            body = body.WithStatements(body.Statements.Add(statement));
                        }
                    }

                    if (whens.Count > 0)
                    {
                        ExpressionSyntax whenCondition = whens[0];
                        for (int i = 1; i < whens.Count; ++i)
                        {
                            whenCondition = SyntaxFactory.BinaryExpression(SyntaxKind.LogicalOrExpression, whenCondition, whens[i]);
                        }

                        body = body.WithStatements(body.Statements.Add(SyntaxFactory.IfStatement(whenCondition, whenBody)));
                    }

                    if (condition == null)
                    {
                        defaultBlock = body
                                       .WithLeadingTrivia(section.GetLeadingTrivia())
                                       .WithTrailingTrivia(section.GetTrailingTrivia());
                        break;
                    }

                    ifNodes.Add(SyntaxFactory.IfStatement(condition, body).WithLeadingTrivia(section.GetLeadingTrivia()));
                }

                var doBlock = SyntaxFactory.Block();
                if (switchConditionVariable != null)
                {
                    doBlock = doBlock.WithStatements(doBlock.Statements.Add(switchConditionVariable));
                }

                doBlock = doBlock.WithStatements(doBlock.Statements.AddRange(ifNodes));

                if (defaultBlock != null)
                {
                    doBlock = doBlock.WithStatements(doBlock.Statements.Add(defaultBlock));
                }

                var doStatement = SyntaxFactory.DoStatement(doBlock, SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression));

                doStatement = doStatement.WithLeadingTrivia(sw.GetLeadingTrivia().Concat(doStatement.GetLeadingTrivia())).WithTrailingTrivia(sw.GetTrailingTrivia());
                return(doStatement.NormalizeWhitespace());
            });

            return(root);
        }
示例#34
0
        public BlockSyntax AddVariablesToBlock(BlockSyntax block)
        {
            //block = block.
            int totalVariables  = Variables.Count;
            int currentVariable = 0;

            //SyntaxToken insertAfter = block.GetFirstToken();
            SyntaxNode insertNode      = null;
            bool       insertIsAfter   = true;
            int        insertSpanStart = 0;

            foreach (var variable in Variables.OrderBy(n => n.Key))
            {
                currentVariable++;
                if (currentVariable < 3)
                {
                    continue;
                }

                if (variable.Value.Static &&
                    variable.Value.Used == true)
                {
                    if (variable.Value.Used == false)
                    {
                        Console.WriteLine();
                    }
                    //SyntaxToken firstToken = block.DescendantTokens().Where(n => n.HasAnnotation(new SyntaxAnnotation("StaticVar", variable.Key.ToString()))).Single();
                    //find the static value
                    object staticValue = GetCurrentValue(variable.Key);

                    //SyntaxKind literalKind;
                    //if (staticValue is string)
                    //{
                    //    staticValue = "\"" + (string)staticValue + "\"";
                    //}

                    //foreach (var node in block.DescendantNodes().OfType<LiteralExpressionSyntax>().Where(n => n.GetText().ToString() == staticValue.ToString()))
                    //{
                    //    Console.WriteLine();
                    //    //insertAfter = node.DescendantNodes().Where(n => n.Kind() == SyntaxKind.SemicolonToken).First();
                    //    break;
                    //}

                    //SyntaxNode fromNode = null;
                    //if (insertAfterNode == null)
                    //{
                    //    fromNode = block;
                    //}
                    //else
                    //{
                    //    fromNode = insertAfterNode;
                    //}

                    //foreach (var token in block.DescendantTokens().Where(n => n.ValueText == staticValue.ToString()).Where(o => o.SpanStart > insertSpanStart).First())
                    //{
                    var tokens = block.DescendantTokens().Where(n => n.ValueText == staticValue.ToString() && n.SpanStart > insertSpanStart);
                    if (tokens.Count() > 0)
                    {
                        var         token       = tokens.First();
                        SyntaxToken insertToken = FindNextSemi(token);
                        if (insertToken.Kind() == SyntaxKind.SemicolonToken)
                        {
                            insertNode    = insertToken.Parent;
                            insertIsAfter = true;
                        }
                        else
                        {
                            if (insertToken.Parent.ChildNodes().Count() > 0)
                            {
                                insertNode    = insertToken.Parent.ChildNodes().First();
                                insertIsAfter = false;
                            }
                            else
                            {
                                insertNode    = insertToken.Parent;
                                insertIsAfter = true;
                            }
                        }
                        insertSpanStart = token.SpanStart;
                        //    break;
                        //}
                    }
                }
                else
                {
                    //SyntaxTokenList newTokens = new SyntaxTokenList();
                    //newTokens = newTokens.Add(insertAfter);
                    LocalDeclarationStatementSyntax localDeclarationStatementSyntax = GetVariableDeclaration(variable.Value);
                    //newTokens.Add(variableToken.DescendantNodesAndTokensAndSelf);
                    //block = block.ReplaceToken(insertAfter, insertAfter);
                    //StatementSyntax statementSyntax = localDeclarationStatementSyntax as StatementSyntax;
                    //var varNode = SyntaxFactory.("\"valid regex\"");
                    //SyntaxAnnotation syntaxAnnotation = new SyntaxAnnotation("Variable", variable.Key.ToString());

                    BlockSyntax addBlock = SyntaxFactory.Block(localDeclarationStatementSyntax); //.WithAdditionalAnnotations(syntaxAnnotation);

                    if (insertNode == null)
                    {
                        block = block.InsertNodesBefore(block.ChildNodes().First(), addBlock.ChildNodes());
                    }
                    else
                    {
                        if (insertIsAfter)
                        {
                            block = block.InsertNodesAfter(insertNode, addBlock.ChildNodes());
                        }
                        else
                        {
                            block = block.InsertNodesBefore(insertNode, addBlock.ChildNodes());
                        }
                    }

                    //insertAfterNode = block.DescendantNodes().OfType<LocalDeclarationStatementSyntax>().Where(n => n.HasAnnotation(syntaxAnnotation)).Single();
                    insertNode      = block.DescendantNodes().OfType <LocalDeclarationStatementSyntax>().Last();
                    insertSpanStart = insertNode.SpanStart;
                    insertIsAfter   = true;
                }
            }
            return(block);
        }
示例#35
0
 private static bool BraceContainsSpan(this BlockSyntax body, TextSpan span)
 {
     return(body.OpenBraceToken.Span.Contains(span) ||
            body.CloseBraceToken.Span.Contains(span));
 }
        private bool GetSpeculativeSemanticModelForMethodBody(SyntaxTreeSemanticModel parentModel, int position, BlockSyntax body, out SemanticModel speculativeModel)
        {
            position = CheckAndAdjustPosition(position);

            var methodSymbol     = (MethodSymbol)this.MemberSymbol;
            var executablebinder = new ExecutableCodeBinder(body, methodSymbol, this.RootBinder.Next); // Strip off ExecutableCodeBinder (see ctor).
            var blockBinder      = executablebinder.GetBinder(body).WithAdditionalFlags(GetSemanticModelBinderFlags());

            speculativeModel = CreateSpeculative(parentModel, methodSymbol, body, blockBinder, position);
            return(true);
        }
        private static BlockSyntax ReformatBlock(Document document, BlockSyntax block)
        {
            var indentationOptions     = IndentationOptions.FromDocument(document);
            var parentIndentationLevel = IndentationHelper.GetIndentationSteps(indentationOptions, GetStatementParent(block.Parent));

            // use one additional step of indentation for lambdas / anonymous methods
            switch (block.Parent.Kind())
            {
            case SyntaxKind.AnonymousMethodExpression:
            case SyntaxKind.SimpleLambdaExpression:
            case SyntaxKind.ParenthesizedLambdaExpression:
                parentIndentationLevel++;
                break;
            }

            var indentationString          = IndentationHelper.GenerateIndentationString(indentationOptions, parentIndentationLevel);
            var statementIndentationString = IndentationHelper.GenerateIndentationString(indentationOptions, parentIndentationLevel + 1);

            var newOpenBraceLeadingTrivia = block.OpenBraceToken.LeadingTrivia
                                            .WithoutTrailingWhitespace()
                                            .Add(SyntaxFactory.Whitespace(indentationString));

            var newOpenBraceTrailingTrivia = block.OpenBraceToken.TrailingTrivia
                                             .WithoutTrailingWhitespace()
                                             .Add(SyntaxFactory.CarriageReturnLineFeed);

            var newCloseBraceLeadingTrivia = block.CloseBraceToken.LeadingTrivia
                                             .WithoutTrailingWhitespace()
                                             .Add(SyntaxFactory.Whitespace(indentationString));

            var newCloseBraceTrailingTrivia = block.CloseBraceToken.TrailingTrivia
                                              .WithoutTrailingWhitespace();

            bool addNewLineAfterCloseBrace;

            switch (block.CloseBraceToken.GetNextToken().Kind())
            {
            case SyntaxKind.CloseParenToken:
            case SyntaxKind.CommaToken:
            case SyntaxKind.SemicolonToken:
                addNewLineAfterCloseBrace = false;
                break;

            default:
                addNewLineAfterCloseBrace = (newCloseBraceTrailingTrivia.Count == 0) || !newCloseBraceTrailingTrivia.Last().IsKind(SyntaxKind.EndOfLineTrivia);
                break;
            }

            if (addNewLineAfterCloseBrace)
            {
                newCloseBraceTrailingTrivia = newCloseBraceTrailingTrivia.Add(SyntaxFactory.CarriageReturnLineFeed);
            }

            var openBraceToken = SyntaxFactory.Token(SyntaxKind.OpenBraceToken)
                                 .WithLeadingTrivia(newOpenBraceLeadingTrivia)
                                 .WithTrailingTrivia(newOpenBraceTrailingTrivia);

            var closeBraceToken = SyntaxFactory.Token(SyntaxKind.CloseBraceToken)
                                  .WithLeadingTrivia(newCloseBraceLeadingTrivia)
                                  .WithTrailingTrivia(newCloseBraceTrailingTrivia);

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

            foreach (var statement in block.Statements)
            {
                var newLeadingTrivia = statement.GetLeadingTrivia()
                                       .WithoutTrailingWhitespace()
                                       .Add(SyntaxFactory.Whitespace(statementIndentationString));

                var newTrailingTrivia = statement.GetTrailingTrivia()
                                        .WithoutTrailingWhitespace()
                                        .Add(SyntaxFactory.CarriageReturnLineFeed);

                var modifiedStatement = statement
                                        .WithLeadingTrivia(newLeadingTrivia)
                                        .WithTrailingTrivia(newTrailingTrivia);

                statements = statements.Add(modifiedStatement);
            }

            return(SyntaxFactory.Block(openBraceToken, statements, closeBraceToken));
        }
 public TokenPair(BlockSyntax block)
 {
     OpenToken  = block.OpenBraceToken;
     CloseToken = block.CloseBraceToken;
 }
        protected override PropertyDeclarationSyntax WithBody(PropertyDeclarationSyntax declaration, BlockSyntax body)
        {
            if (body == null)
            {
                return(declaration.WithAccessorList(null));
            }

            throw new InvalidOperationException();
        }
        private bool TryComputeWeightedDistance(BlockSyntax leftBlock, BlockSyntax rightBlock, out double distance)
        {
            // No block can be matched with the root block.
            // Note that in constructors the root is the constructor declaration, since we need to include
            // the constructor initializer in the match.
            if (leftBlock.Parent == null ||
                rightBlock.Parent == null ||
                leftBlock.Parent.IsKind(SyntaxKind.ConstructorDeclaration) ||
                rightBlock.Parent.IsKind(SyntaxKind.ConstructorDeclaration))
            {
                distance = 0.0;
                return(true);
            }

            if (GetLabel(leftBlock.Parent) != GetLabel(rightBlock.Parent))
            {
                distance = 0.2 + 0.8 * ComputeWeightedBlockDistance(leftBlock, rightBlock);
                return(true);
            }

            switch (leftBlock.Parent.Kind())
            {
            case SyntaxKind.IfStatement:
            case SyntaxKind.ForEachStatement:
            case SyntaxKind.ForEachVariableStatement:
            case SyntaxKind.ForStatement:
            case SyntaxKind.WhileStatement:
            case SyntaxKind.DoStatement:
            case SyntaxKind.FixedStatement:
            case SyntaxKind.LockStatement:
            case SyntaxKind.UsingStatement:
            case SyntaxKind.SwitchSection:
            case SyntaxKind.ParenthesizedLambdaExpression:
            case SyntaxKind.SimpleLambdaExpression:
            case SyntaxKind.AnonymousMethodExpression:
                // value distance of the block body is included:
                distance = GetDistance(leftBlock.Parent, rightBlock.Parent);
                return(true);

            case SyntaxKind.CatchClause:
                var leftCatch  = (CatchClauseSyntax)leftBlock.Parent;
                var rightCatch = (CatchClauseSyntax)rightBlock.Parent;
                if (leftCatch.Declaration == null && leftCatch.Filter == null &&
                    rightCatch.Declaration == null && rightCatch.Filter == null)
                {
                    var leftTry  = (TryStatementSyntax)leftCatch.Parent !;
                    var rightTry = (TryStatementSyntax)rightCatch.Parent !;

                    distance = 0.5 * ComputeValueDistance(leftTry.Block, rightTry.Block) +
                               0.5 * ComputeValueDistance(leftBlock, rightBlock);
                }
                else
                {
                    // value distance of the block body is included:
                    distance = GetDistance(leftBlock.Parent, rightBlock.Parent);
                }

                return(true);

            case SyntaxKind.Block:
            case SyntaxKind.LabeledStatement:
                distance = ComputeWeightedBlockDistance(leftBlock, rightBlock);
                return(true);

            case SyntaxKind.UnsafeStatement:
            case SyntaxKind.CheckedStatement:
            case SyntaxKind.UncheckedStatement:
            case SyntaxKind.ElseClause:
            case SyntaxKind.FinallyClause:
            case SyntaxKind.TryStatement:
                distance = 0.2 * ComputeValueDistance(leftBlock, rightBlock);
                return(true);

            default:
                throw ExceptionUtilities.UnexpectedValue(leftBlock.Parent.Kind());
            }
        }
示例#41
0
 internal StatementContainer(BlockSyntax block)
     : this()
 {
     Block      = block;
     Statements = block.Statements;
 }
 private static bool IsEmpty(BlockSyntax node)
 {
     return(!node.Statements.Any() && !ContainsComment(node));
 }
        private static void Analyze(SyntaxNodeAnalysisContext context, SyntaxNode node, SyntaxToken asyncKeyword, BlockSyntax body)
        {
            if (asyncKeyword.IsKind(SyntaxKind.AsyncKeyword) &&
                body?.IsMissing == false &&
                !node.SpanContainsDirectives())
            {
                SyntaxList <StatementSyntax> statements = body.Statements;

                if (statements.Any())
                {
                    StatementSyntax statement = statements.LastOrDefault(f => !f.IsKind(SyntaxKind.LocalFunctionStatement));

                    if (statement != null)
                    {
                        SyntaxKind kind = statement.Kind();

                        if (kind == SyntaxKind.ReturnStatement)
                        {
                            var returnStatement = (ReturnStatementSyntax)statement;

                            AwaitExpressionSyntax awaitExpression = GetAwaitExpressionOrDefault(returnStatement);

                            if (awaitExpression != null)
                            {
                                HashSet <AwaitExpressionSyntax> awaitExpressions = CollectAwaitExpressions(body, TextSpan.FromBounds(body.SpanStart, returnStatement.Span.End));

                                if (awaitExpressions != null)
                                {
                                    if (awaitExpressions.Count == 1)
                                    {
                                        if (ReturnTypeAndAwaitTypeEquals(node, awaitExpression, context.SemanticModel, context.CancellationToken))
                                        {
                                            ReportDiagnostic(context, asyncKeyword, awaitExpression);
                                        }
                                    }
                                    else
                                    {
                                        int index = statements.IndexOf(returnStatement);

                                        if (index > 0)
                                        {
                                            StatementSyntax previousStatement = statements[index - 1];

                                            SyntaxKind previousStatementKind = previousStatement.Kind();

                                            if (previousStatementKind == SyntaxKind.IfStatement)
                                            {
                                                Analyze(context, node, asyncKeyword, awaitExpression, awaitExpressions, GetAwaitExpressionsFromIfStatement((IfStatementSyntax)previousStatement, endsWithElse: false));
                                            }
                                            else if (previousStatementKind == SyntaxKind.SwitchStatement)
                                            {
                                                Analyze(context, node, asyncKeyword, awaitExpression, awaitExpressions, GetAwaitExpressionsFromSwitchStatement((SwitchStatementSyntax)previousStatement, containsDefaultSection: false));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else if (kind == SyntaxKind.IfStatement)
                        {
                            Analyze(context, node, body, asyncKeyword, GetAwaitExpressionsFromIfStatement((IfStatementSyntax)statement, endsWithElse: true));
                        }
                        else if (kind == SyntaxKind.SwitchStatement)
                        {
                            Analyze(context, node, body, asyncKeyword, GetAwaitExpressionsFromSwitchStatement((SwitchStatementSyntax)statement, containsDefaultSection: true));
                        }
                    }
                }
            }
        }
示例#44
0
        public static IfStatementSyntax IfStatement(SyntaxNode condition, BlockSyntax thenBlock, BlockSyntax elseBlock)
        {
            if (!elseBlock.Statements.Any())
            {
                return(SyntaxFactory.IfStatement(condition as ExpressionSyntax, thenBlock));
            }

            return(SyntaxFactory.IfStatement(condition as ExpressionSyntax, thenBlock).WithElse(SyntaxFactory.ElseClause(elseBlock)));
        }
        private static bool CanReplaceAnonymousWithLocalFunction(
            SemanticModel semanticModel, INamedTypeSymbol?expressionTypeOpt, ISymbol local, BlockSyntax block,
            AnonymousFunctionExpressionSyntax anonymousFunction, out ImmutableArray <Location> referenceLocations, CancellationToken cancellationToken)
        {
            // Check all the references to the anonymous function and disallow the conversion if
            // they're used in certain ways.
            var references = ArrayBuilder <Location> .GetInstance();

            referenceLocations = ImmutableArray <Location> .Empty;
            var anonymousFunctionStart = anonymousFunction.SpanStart;

            foreach (var descendentNode in block.DescendantNodes())
            {
                var descendentStart = descendentNode.Span.Start;
                if (descendentStart <= anonymousFunctionStart)
                {
                    // This node is before the local declaration.  Can ignore it entirely as it could
                    // not be an access to the local.
                    continue;
                }

                if (descendentNode.IsKind(SyntaxKind.IdentifierName, out IdentifierNameSyntax? identifierName))
                {
                    if (identifierName.Identifier.ValueText == local.Name &&
                        local.Equals(semanticModel.GetSymbolInfo(identifierName, cancellationToken).GetAnySymbol()))
                    {
                        if (identifierName.IsWrittenTo(semanticModel, cancellationToken))
                        {
                            // Can't change this to a local function if it is assigned to.
                            return(false);
                        }

                        var nodeToCheck = identifierName.WalkUpParentheses();
                        if (nodeToCheck.Parent is BinaryExpressionSyntax)
                        {
                            // Can't change this if they're doing things like delegate addition with
                            // the lambda.
                            return(false);
                        }

                        if (nodeToCheck.Parent is InvocationExpressionSyntax invocationExpression)
                        {
                            references.Add(invocationExpression.GetLocation());
                        }
                        else if (nodeToCheck.Parent is MemberAccessExpressionSyntax memberAccessExpression)
                        {
                            if (memberAccessExpression.Parent is InvocationExpressionSyntax explicitInvocationExpression &&
                                memberAccessExpression.Name.Identifier.ValueText == WellKnownMemberNames.DelegateInvokeName)
                            {
                                references.Add(explicitInvocationExpression.GetLocation());
                            }
                            else
                            {
                                // They're doing something like "del.ToString()".  Can't do this with a
                                // local function.
                                return(false);
                            }
                        }
                        else
                        {
                            references.Add(nodeToCheck.GetLocation());
                        }

                        var convertedType = semanticModel.GetTypeInfo(nodeToCheck, cancellationToken).ConvertedType;
                        if (!convertedType.IsDelegateType())
                        {
                            // We can't change this anonymous function into a local function if it is
                            // converted to a non-delegate type (i.e. converted to 'object' or
                            // 'System.Delegate'). Local functions are not convertible to these types.
                            // They're only convertible to other delegate types.
                            return(false);
                        }

                        if (nodeToCheck.IsInExpressionTree(semanticModel, expressionTypeOpt, cancellationToken))
                        {
                            // Can't reference a local function inside an expression tree.
                            return(false);
                        }
                    }
                }
            }
 public BlockRewriter(SyntaxToken parentToken, SyntaxToken newParentToken, BlockSyntax block, BlockSyntax newBlock, SyntaxToken nextToken, SyntaxToken newNextToken)
 {
     this.parentToken    = parentToken;
     this.newParentToken = newParentToken;
     this.block          = block;
     this.newBlock       = newBlock;
     this.nextToken      = nextToken;
     this.newNextToken   = newNextToken;
 }
示例#47
0
 public override void VisitBlock(BlockSyntax node)
 {
     cancellationToken.ThrowIfCancellationRequested();
     base.VisitBlock(node);
 }
 protected override OperatorDeclarationSyntax WithBody(OperatorDeclarationSyntax declaration, BlockSyntax body)
 => declaration.WithBody(body);
        private static SyntaxNode ReformatBlockAndParent(Document document, SyntaxNode syntaxRoot, BlockSyntax block)
        {
            var parentLastToken = block.OpenBraceToken.GetPreviousToken();

            var parentEndLine  = parentLastToken.GetEndLine();
            var blockStartLine = block.OpenBraceToken.GetLine();

            var newParentLastToken = parentLastToken;

            if (parentEndLine == blockStartLine)
            {
                var newTrailingTrivia = parentLastToken.TrailingTrivia
                                        .WithoutTrailingWhitespace()
                                        .Add(SyntaxFactory.CarriageReturnLineFeed);

                newParentLastToken = newParentLastToken.WithTrailingTrivia(newTrailingTrivia);
            }

            var parentNextToken = block.CloseBraceToken.GetNextToken();

            var nextTokenLine  = parentNextToken.GetLine();
            var blockCloseLine = block.CloseBraceToken.GetEndLine();

            var newParentNextToken = parentNextToken;

            if (nextTokenLine == blockCloseLine)
            {
                newParentNextToken = newParentNextToken.WithLeadingTrivia(parentLastToken.LeadingTrivia);
            }

            var newBlock = ReformatBlock(document, block);
            var rewriter = new BlockRewriter(parentLastToken, newParentLastToken, block, newBlock, parentNextToken, newParentNextToken);

            var newSyntaxRoot = rewriter.Visit(syntaxRoot);

            return(newSyntaxRoot.WithoutFormatting());
        }
示例#50
0
        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));
        }
 private static bool IsNested(BlockSyntax node)
 {
     return(!AllowedContainerKinds.Contains(node.Parent.Kind()));
 }
示例#52
0
        private Dictionary <int, BlockInfo> collectBlocks(BlockSyntax body)
        {
            BlockInfoCollector blockInfo = new BlockInfoCollector(root);

            return(blockInfo.Collect(body));
        }
        private static void Analyze(SyntaxNodeAnalysisContext context, SyntaxNode node, BlockSyntax body)
        {
            if (body == null)
            {
                return;
            }

            if (body.ContainsDiagnostics)
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = body.Statements;

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

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

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

            ExpressionSyntax returnExpression = returnStatement.Expression;

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

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

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

            SimpleIfStatementInfo simpleIf = SyntaxInfo.SimpleIfStatementInfo(ifStatement);

            if (!simpleIf.Success)
            {
                return;
            }

            StatementSyntax statement = simpleIf.IfStatement.SingleNonBlockStatementOrDefault();

            if (statement == null)
            {
                return;
            }

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(statement);

            if (!assignmentInfo.Success)
            {
                return;
            }

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

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

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

            if (!nullCheck.Success)
            {
                return;
            }

            ExpressionSyntax expression = nullCheck.Expression;

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

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

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

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

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

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

            context.ReportDiagnostic(
                DiagnosticDescriptors.SimplifyLazyInitialization,
                Location.Create(node.SyntaxTree, TextSpan.FromBounds(ifStatement.SpanStart, returnStatement.Span.End)));
        }
 private static bool IsNestedAndEmpty(BlockSyntax node)
 {
     return(IsNested(node) && IsEmpty(node));
 }
示例#55
0
        /// <summary>
        /// Converts a synchronous method to be asynchronous, if it is not already async.
        /// </summary>
        /// <param name="method">The method to convert.</param>
        /// <param name="document">The document.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// The new Document and method syntax, or the original if it was already async.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">
        /// method
        /// or
        /// document
        /// or
        /// originalMethodSymbol
        /// </exception>
        internal static async Task <Tuple <Document, MethodDeclarationSyntax> > MakeMethodAsync(this MethodDeclarationSyntax method, Document document, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            if (method.Modifiers.Any(SyntaxKind.AsyncKeyword))
            {
                // Already asynchronous.
                return(Tuple.Create(document, method));
            }

            DocumentId documentId    = document.Id;
            var        semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var methodSymbol = semanticModel.GetDeclaredSymbol(method);

            bool       hasReturnValue;
            TypeSyntax returnType = method.ReturnType;

            if (!HasAsyncCompatibleReturnType(methodSymbol))
            {
                hasReturnValue = (method.ReturnType as PredefinedTypeSyntax)?.Keyword.Kind() != SyntaxKind.VoidKeyword;

                // Determine new return type.
                returnType = hasReturnValue
                    ? QualifyName(
                    Namespaces.SystemThreadingTasks,
                    SyntaxFactory.GenericName(SyntaxFactory.Identifier(nameof(Task)))
                    .AddTypeArgumentListArguments(method.ReturnType))
                    : SyntaxFactory.ParseTypeName(typeof(Task).FullName);
                returnType = returnType
                             .WithAdditionalAnnotations(Simplifier.Annotation)
                             .WithTrailingTrivia(method.ReturnType.GetTrailingTrivia());
            }
            else
            {
                TypeSyntax t = method.ReturnType;
                while (t is QualifiedNameSyntax q)
                {
                    t = q.Right;
                }

                hasReturnValue = t is GenericNameSyntax;
            }

            // Fix up any return statements to await on the Task it would have returned.
            bool        returnTypeChanged = method.ReturnType != returnType;
            BlockSyntax updatedBody       = UpdateStatementsForAsyncMethod(
                method.Body,
                semanticModel,
                hasReturnValue,
                returnTypeChanged);

            // Apply the changes to the document, and null out stale data.
            SyntaxAnnotation methodBookmark;

            (document, method, methodBookmark) = await UpdateDocumentAsync(
                document,
                method,
                m => m
                .WithBody(updatedBody)
                .AddModifiers(SyntaxFactory.Token(SyntaxKind.AsyncKeyword))
                .WithReturnType(returnType),
                cancellationToken).ConfigureAwait(false);

            semanticModel = null;
            methodSymbol  = null;

            // Rename the method to have an Async suffix if we changed the return type,
            // and it doesn't already have that suffix.
            if (returnTypeChanged && !method.Identifier.ValueText.EndsWith(VSTHRD200UseAsyncNamingConventionAnalyzer.MandatoryAsyncSuffix, StringComparison.Ordinal))
            {
                string newName = method.Identifier.ValueText + VSTHRD200UseAsyncNamingConventionAnalyzer.MandatoryAsyncSuffix;

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

                methodSymbol = semanticModel.GetDeclaredSymbol(method, cancellationToken);
                var solution = await Renamer.RenameSymbolAsync(
                    document.Project.Solution,
                    methodSymbol,
                    newName,
                    document.Project.Solution.Workspace.Options,
                    cancellationToken).ConfigureAwait(false);

                document      = solution.GetDocument(document.Id);
                semanticModel = null;
                methodSymbol  = null;
                var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                method = (MethodDeclarationSyntax)root.GetAnnotatedNodes(methodBookmark).Single();
            }

            // Update callers to await calls to this method if we made it awaitable.
            if (returnTypeChanged)
            {
                semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                methodSymbol = semanticModel.GetDeclaredSymbol(method, cancellationToken);
                SyntaxAnnotation  callerAnnotation;
                Solution          solution = document.Project.Solution;
                List <DocumentId> annotatedDocumentIds;
                (solution, callerAnnotation, annotatedDocumentIds) = await AnnotateAllCallersAsync(solution, methodSymbol, cancellationToken).ConfigureAwait(false);

                foreach (DocumentId docId in annotatedDocumentIds)
                {
                    document = solution.GetDocument(docId);
                    var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                    var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);

                    var rewriter = new AwaitCallRewriter(callerAnnotation);
                    root     = rewriter.Visit(root);
                    solution = solution.GetDocument(tree).WithSyntaxRoot(root).Project.Solution;
                }

                foreach (DocumentId docId in annotatedDocumentIds)
                {
                    document = solution.GetDocument(docId);
                    var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                    var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);

                    for (var node = root.GetAnnotatedNodes(callerAnnotation).FirstOrDefault(); node != null; node = root.GetAnnotatedNodes(callerAnnotation).FirstOrDefault())
                    {
                        var callingMethod = node.FirstAncestorOrSelf <MethodDeclarationSyntax>();
                        if (callingMethod != null)
                        {
                            (document, callingMethod) = await MakeMethodAsync(callingMethod, document, cancellationToken).ConfigureAwait(false);

                            // Clear all annotations of callers from this method so we don't revisit it.
                            root = await callingMethod.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

                            var annotationRemover = new RemoveAnnotationRewriter(callerAnnotation);
                            root     = root.ReplaceNode(callingMethod, annotationRemover.Visit(callingMethod));
                            document = document.WithSyntaxRoot(root);
                            root     = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
                        }
                        else
                        {
                            // Clear all annotations of callers from this method so we don't revisit it.
                            root = await node.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

                            root     = root.ReplaceNode(node, node.WithoutAnnotations(callerAnnotation));
                            document = document.WithSyntaxRoot(root);
                            root     = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
                        }
                    }

                    solution = document.Project.Solution;
                }

                // Make sure we return the latest of everything.
                document = solution.GetDocument(documentId);
                var finalTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                var finalRoot = await finalTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

                method = (MethodDeclarationSyntax)finalRoot.GetAnnotatedNodes(methodBookmark).Single();
            }

            return(Tuple.Create(document, method));
        }
示例#56
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddArgumentList) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReorderModifiers) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReturnDefaultValue) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddMissingType) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveSemicolon) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConditionalAccess) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.ChangeForEachType))
            {
                return;
            }

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

            if (!TryFindToken(root, context.Span.Start, out SyntaxToken token))
            {
                return;
            }

            SyntaxKind kind = token.Kind();

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.OperatorCannotBeAppliedToOperand:
                {
                    if (kind == SyntaxKind.QuestionToken &&
                        token.Parent is ConditionalAccessExpressionSyntax conditionalAccess)
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

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

                        if (typeSymbol?.IsErrorType() == false &&
                            !typeSymbol.IsNullableType())
                        {
                            if (typeSymbol.IsValueType)
                            {
                                if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConditionalAccess))
                                {
                                    CodeAction codeAction = CodeAction.Create(
                                        "Remove '?' operator",
                                        cancellationToken =>
                                        {
                                            var textChange = new TextChange(token.Span, "");
                                            return(context.Document.WithTextChangeAsync(textChange, cancellationToken));
                                        },
                                        GetEquivalenceKey(diagnostic));

                                    context.RegisterCodeFix(codeAction, diagnostic);
                                }
                            }
                            else if (typeSymbol.IsReferenceType)
                            {
                                if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddArgumentList) &&
                                    conditionalAccess.WhenNotNull is MemberBindingExpressionSyntax memberBindingExpression)
                                {
                                    ConditionalAccessExpressionSyntax newNode = conditionalAccess.WithWhenNotNull(
                                        InvocationExpression(
                                            memberBindingExpression.WithoutTrailingTrivia(),
                                            ArgumentList().WithTrailingTrivia(memberBindingExpression.GetTrailingTrivia())));

                                    CodeAction codeAction = CodeAction.Create(
                                        "Add argument list",
                                        cancellationToken => context.Document.ReplaceNodeAsync(conditionalAccess, newNode, cancellationToken),
                                        GetEquivalenceKey(diagnostic));

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

                        if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddArgumentList))
                        {
                            break;
                        }

                        if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConditionalAccess))
                        {
                        }
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.PartialModifierCanOnlyAppearImmediatelyBeforeClassStructInterfaceOrVoid:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReorderModifiers))
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.MoveModifier(context, diagnostic, token.Parent, token);
                    break;
                }

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

                    if (!(token.Parent is ParameterSyntax parameter))
                    {
                        break;
                    }

                    ExpressionSyntax value = parameter.Default?.Value;

                    if (value == null)
                    {
                        break;
                    }

                    if (value.Kind() != SyntaxKind.NullLiteralExpression)
                    {
                        break;
                    }

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

                    CodeFixRegistrator.ReplaceNullWithDefaultValue(context, diagnostic, value, semanticModel);
                    break;
                }

                case CompilerDiagnosticIdentifiers.ObjectOfTypeConvertibleToTypeIsRequired:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReturnDefaultValue))
                    {
                        break;
                    }

                    if (token.Kind() != SyntaxKind.ReturnKeyword)
                    {
                        break;
                    }

                    if (!token.IsParentKind(SyntaxKind.ReturnStatement))
                    {
                        break;
                    }

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

                    ISymbol symbol = semanticModel.GetEnclosingSymbol(token.SpanStart, context.CancellationToken);

                    if (symbol == null)
                    {
                        break;
                    }

                    SymbolKind symbolKind = symbol.Kind;

                    ITypeSymbol typeSymbol = null;

                    if (symbolKind == SymbolKind.Method)
                    {
                        var methodSymbol = (IMethodSymbol)symbol;

                        typeSymbol = methodSymbol.ReturnType;

                        if (methodSymbol.IsAsync &&
                            (typeSymbol is INamedTypeSymbol namedTypeSymbol))
                        {
                            ImmutableArray <ITypeSymbol> typeArguments = namedTypeSymbol.TypeArguments;

                            if (typeArguments.Any())
                            {
                                typeSymbol = typeArguments[0];
                            }
                        }
                    }
                    else if (symbolKind == SymbolKind.Property)
                    {
                        typeSymbol = ((IPropertySymbol)symbol).Type;
                    }
                    else
                    {
                        Debug.Fail(symbolKind.ToString());
                    }

                    if (typeSymbol == null)
                    {
                        break;
                    }

                    if (typeSymbol.Kind == SymbolKind.ErrorType)
                    {
                        break;
                    }

                    if (!typeSymbol.SupportsExplicitDeclaration())
                    {
                        break;
                    }

                    var returnStatement = (ReturnStatementSyntax)token.Parent;

                    CodeAction codeAction = CodeAction.Create(
                        "Return default value",
                        cancellationToken =>
                        {
                            ExpressionSyntax expression = typeSymbol.GetDefaultValueSyntax(semanticModel, returnStatement.SpanStart);

                            ReturnStatementSyntax newNode = returnStatement.WithExpression(expression);

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

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

                case CompilerDiagnosticIdentifiers.TypeExpected:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddMissingType))
                    {
                        break;
                    }

                    if (token.Kind() != SyntaxKind.CloseParenToken)
                    {
                        break;
                    }

                    if (!(token.Parent is DefaultExpressionSyntax defaultExpression))
                    {
                        break;
                    }

                    if (!(defaultExpression.Type is IdentifierNameSyntax identifierName))
                    {
                        break;
                    }

                    if (!identifierName.IsMissing)
                    {
                        break;
                    }

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

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

                    ITypeSymbol convertedType = typeInfo.ConvertedType;

                    if (convertedType?.SupportsExplicitDeclaration() != true)
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        $"Add type '{SymbolDisplay.ToMinimalDisplayString(convertedType, semanticModel, defaultExpression.SpanStart, SymbolDisplayFormats.Default)}'",
                        cancellationToken =>
                        {
                            TypeSyntax newNode = convertedType.ToMinimalTypeSyntax(semanticModel, defaultExpression.SpanStart);

                            newNode = newNode
                                      .WithTriviaFrom(identifierName)
                                      .WithFormatterAnnotation();

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

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

                case CompilerDiagnosticIdentifiers.SemicolonAfterMethodOrAccessorBlockIsNotValid:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveSemicolon))
                    {
                        break;
                    }

                    if (token.Kind() != SyntaxKind.SemicolonToken)
                    {
                        break;
                    }

                    switch (token.Parent)
                    {
                    case MethodDeclarationSyntax methodDeclaration:
                    {
                        BlockSyntax body = methodDeclaration.Body;

                        if (body == null)
                        {
                            break;
                        }

                        CodeAction codeAction = CodeAction.Create(
                            "Remove semicolon",
                            cancellationToken =>
                                {
                                    SyntaxTriviaList trivia = body
                                                              .GetTrailingTrivia()
                                                              .EmptyIfWhitespace()
                                                              .AddRange(token.LeadingTrivia.EmptyIfWhitespace())
                                                              .AddRange(token.TrailingTrivia);

                                    MethodDeclarationSyntax newNode = methodDeclaration
                                                                      .WithBody(body.WithTrailingTrivia(trivia))
                                                                      .WithSemicolonToken(default(SyntaxToken));

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

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

                    case PropertyDeclarationSyntax propertyDeclaration:
                    {
                        AccessorListSyntax accessorList = propertyDeclaration.AccessorList;

                        if (accessorList == null)
                        {
                            break;
                        }

                        CodeAction codeAction = CodeAction.Create(
                            "Remove semicolon",
                            cancellationToken =>
                                {
                                    SyntaxTriviaList trivia = accessorList
                                                              .GetTrailingTrivia()
                                                              .EmptyIfWhitespace()
                                                              .AddRange(token.LeadingTrivia.EmptyIfWhitespace())
                                                              .AddRange(token.TrailingTrivia);

                                    PropertyDeclarationSyntax newNode = propertyDeclaration
                                                                        .WithAccessorList(accessorList.WithTrailingTrivia(trivia))
                                                                        .WithSemicolonToken(default(SyntaxToken));

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

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

                    case AccessorDeclarationSyntax accessorDeclaration:
                    {
                        BlockSyntax body = accessorDeclaration.Body;

                        if (body == null)
                        {
                            break;
                        }

                        CodeAction codeAction = CodeAction.Create(
                            "Remove semicolon",
                            cancellationToken =>
                                {
                                    SyntaxTriviaList trivia = body
                                                              .GetTrailingTrivia()
                                                              .EmptyIfWhitespace()
                                                              .AddRange(token.LeadingTrivia.EmptyIfWhitespace())
                                                              .AddRange(token.TrailingTrivia);

                                    AccessorDeclarationSyntax newNode = accessorDeclaration
                                                                        .WithBody(body.WithTrailingTrivia(trivia))
                                                                        .WithSemicolonToken(default(SyntaxToken));

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

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

                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotConvertType:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ChangeForEachType))
                    {
                        break;
                    }

                    if (token.Kind() != SyntaxKind.ForEachKeyword)
                    {
                        break;
                    }

                    if (!(token.Parent is ForEachStatementSyntax forEachStatement))
                    {
                        break;
                    }

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

                    ForEachStatementInfo info = semanticModel.GetForEachStatementInfo(forEachStatement);

                    ITypeSymbol typeSymbol = info.ElementType;

                    if (typeSymbol.SupportsExplicitDeclaration())
                    {
                        CodeFixRegistrator.ChangeType(context, diagnostic, forEachStatement.Type, typeSymbol, semanticModel, CodeFixIdentifiers.ChangeForEachType);
                    }

                    CodeFixRegistrator.ChangeTypeToVar(context, diagnostic, forEachStatement.Type, CodeFixIdentifiers.ChangeTypeToVar);
                    break;
                }
                }
            }
        }
示例#57
0
 // 块语句
 public virtual void VisitBlockSyntax(BlockSyntax value)
 {
     DefaultVisit(value);
 }
示例#58
0
        private BlockSyntax InsertLocalVariableStatementFor(ExpressionSyntax callSite, string methodName, BlockSyntax block)
        {
            var typeSyntax = VarTypeSyntax(block);
            var lineSpan   = callSite.SyntaxTree.GetLineSpan(callSite.Span);

            var varDecl = SyntaxFactory.VariableDeclaration(
                typeSyntax,
                SyntaxFactory.SeparatedList(new[] { VariableDeclaratorFor(callSite, string.Format("{0}_{1}", lineSpan.StartLinePosition.Line, lineSpan.StartLinePosition.Character), methodName) }));

            var newBlockBody = InsertLocalVariableDeclarationBeforeCallSite(block, varDecl, callSite);

            return(block.WithStatements(newBlockBody));
        }
示例#59
0
 public override void VisitBlock(BlockSyntax node)
 {
     _usingDeclarations.Add(0);
     base.VisitBlock(node);
     _usingDeclarations.RemoveAt(_usingDeclarations.Count - 1);
 }
 private static bool ContainsComment(BlockSyntax node)
 {
     return(ContainsComment(node.OpenBraceToken.TrailingTrivia) || ContainsComment(node.CloseBraceToken.LeadingTrivia));
 }