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); }
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); }
public override void VisitBlock(BlockSyntax node) { foreach (var statement in node.Statements) { base.Visit(statement); } }
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); }
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(); }
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 : ""); }
public static BlockSyntax AddTrailingBlankLine(BlockSyntax block) { Debug.Assert(block != null && NeedsTrailingBlankLine(block)); return block .WithTrailingTrivia(block.GetTrailingTrivia().Add(SyntaxFactory.CarriageReturnLineFeed)) .WithAdditionalAnnotations(Formatter.Annotation); }
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); }
public override void VisitBlock(BlockSyntax node) { var oldIsInScope = isInScope; if (!contextParents.Contains(node)) isInScope = false; base.VisitBlock(node); if (!isInScope && oldIsInScope) isInScope = true; }
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); }
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); }
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; }
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; }
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; }
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; }
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; }
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()); } } } }
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())); }
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); }
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); }
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()); } }
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)); } } } } }
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; }
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()); }
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())); }
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)); }
/// <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)); }
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; } } } }
// 块语句 public virtual void VisitBlockSyntax(BlockSyntax value) { DefaultVisit(value); }
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)); }
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)); }