private IndentationResult GetDefaultIndentationFromTokenLine(SyntaxToken token, int?additionalSpace = null) { var spaceToAdd = additionalSpace ?? this.OptionSet.GetOption(FormattingOptions.IndentationSize, token.Language); var sourceText = LineToBeIndented.Text; // find line where given token is var givenTokenLine = sourceText.Lines.GetLineFromPosition(token.SpanStart); // find right position var position = GetCurrentPositionNotBelongToEndOfFileToken(LineToBeIndented.Start); // find containing non expression node var nonExpressionNode = token.GetAncestors <SyntaxNode>().FirstOrDefault(n => n is StatementSyntax); if (nonExpressionNode == null) { // well, I can't find any non expression node. use default behavior return(IndentFromStartOfLine(Finder.GetIndentationOfCurrentPosition(Tree, token, position, spaceToAdd, CancellationToken))); } // find line where first token of the node is var firstTokenLine = sourceText.Lines.GetLineFromPosition(nonExpressionNode.GetFirstToken(includeZeroWidth: true).SpanStart); // single line expression if (firstTokenLine.LineNumber == givenTokenLine.LineNumber) { return(IndentFromStartOfLine(Finder.GetIndentationOfCurrentPosition(Tree, token, position, spaceToAdd, CancellationToken))); } // okay, looks like containing node is written over multiple lines, in that case, give same indentation as given token return(GetIndentationOfLine(givenTokenLine)); }
private SyntaxNode GetQueryExpressionClause(SyntaxToken token) { var clause = token.GetAncestors <SyntaxNode>().FirstOrDefault(n => n is QueryClauseSyntax || n is SelectOrGroupClauseSyntax); if (clause != null) { return(clause); } // If this is a query continuation, use the last clause of its parenting query. var body = token.GetAncestor <QueryBodySyntax>(); if (body != null) { if (body.SelectOrGroup.IsMissing) { return(body.Clauses.LastOrDefault()); } else { return(body.SelectOrGroup); } } return(null); }
public static ISymbol GetDeclaredSymbol(this SemanticModel semanticModel, SyntaxToken token, CancellationToken cancellationToken) { var location = token.GetLocation(); var q = from node in token.GetAncestors <SyntaxNode>() let symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken) where symbol != null && symbol.Locations.Contains(location) select symbol; return(q.FirstOrDefault()); }
public static bool IsUnsafeContext(this SyntaxToken targetToken) { return (targetToken.GetAncestors <StatementSyntax>().Any(s => s.IsKind(SyntaxKind.UnsafeStatement)) || targetToken.GetAncestors <MemberDeclarationSyntax>().Any(m => m.GetModifiers().Any(SyntaxKind.UnsafeKeyword))); }
public ISymbol GetDeclaredSymbol(SemanticModel semanticModel, SyntaxToken token, CancellationToken cancellationToken) { var location = token.GetLocation(); var q = from node in token.GetAncestors<SyntaxNode>() let symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken) where symbol != null && symbol.Locations.Contains(location) select symbol; return q.FirstOrDefault(); }
public override SyntaxToken VisitToken(SyntaxToken token) { var shouldCheckTrivia = _stringAndCommentTextSpans.Contains(token.Span); _isProcessingTrivia += shouldCheckTrivia ? 1 : 0; var newToken = base.VisitToken(token); _isProcessingTrivia -= shouldCheckTrivia ? 1 : 0; // Handle Alias annotations newToken = UpdateAliasAnnotation(newToken); // Rename matches in strings and comments newToken = RenameWithinToken(token, newToken); // We don't want to annotate XmlName with RenameActionAnnotation if (newToken.Parent.IsKind(SyntaxKind.XmlName)) { return newToken; } bool isRenameLocation = IsRenameLocation(token); // if this is a reference location, or the identifier token's name could possibly // be a conflict, we need to process this token var isOldText = token.ValueText == _originalText; var tokenNeedsConflictCheck = isRenameLocation || token.ValueText == _replacementText || isOldText || _possibleNameConflicts.Contains(token.ValueText); if (tokenNeedsConflictCheck) { newToken = RenameAndAnnotateAsync(token, newToken, isRenameLocation, isOldText).WaitAndGetResult(_cancellationToken); if (!_isProcessingComplexifiedSpans) { _invocationExpressionsNeedingConflictChecks.AddRange(token.GetAncestors<InvocationExpressionSyntax>()); } } return newToken; }
private static SyntaxNode GetExpansionTarget(SyntaxToken token) { // get the directly enclosing statement var enclosingStatement = token.GetAncestors(n => n is StatementSyntax).FirstOrDefault(); // System.Func<int, int> myFunc = arg => X; SyntaxNode possibleLambdaExpression = enclosingStatement == null ? token.GetAncestors(n => n is SimpleLambdaExpressionSyntax || n is ParenthesizedLambdaExpressionSyntax).FirstOrDefault() : null; if (possibleLambdaExpression != null) { var lambdaExpression = ((LambdaExpressionSyntax)possibleLambdaExpression); if (lambdaExpression.Body is ExpressionSyntax) { return lambdaExpression.Body; } } // int M() => X; var possibleArrowExpressionClause = enclosingStatement == null ? token.GetAncestors<ArrowExpressionClauseSyntax>().FirstOrDefault() : null; if (possibleArrowExpressionClause != null) { return possibleArrowExpressionClause.Expression; } var enclosingNameMemberCrefOrnull = token.GetAncestors(n => n is NameMemberCrefSyntax).LastOrDefault(); if (enclosingNameMemberCrefOrnull != null) { if (token.Parent is TypeSyntax && token.Parent.Parent is TypeSyntax) { enclosingNameMemberCrefOrnull = null; } } var enclosingXmlNameAttr = token.GetAncestors(n => n is XmlNameAttributeSyntax).FirstOrDefault(); if (enclosingXmlNameAttr != null) { return null; } var enclosingInitializer = token.GetAncestors<EqualsValueClauseSyntax>().FirstOrDefault(); if (enclosingStatement == null && enclosingInitializer != null && enclosingInitializer.Parent is VariableDeclaratorSyntax) { return enclosingInitializer.Value; } var attributeSyntax = token.GetAncestor<AttributeSyntax>(); if (attributeSyntax != null) { return attributeSyntax; } // there seems to be no statement above this one. Let's see if we can at least get an SimpleNameSyntax return enclosingStatement ?? enclosingNameMemberCrefOrnull ?? token.GetAncestors(n => n is SimpleNameSyntax).FirstOrDefault(); }
private SyntaxToken SimplifyIdentifierToken( SyntaxToken token, SemanticModel semanticModel, OptionSet optionSet, CancellationToken cancellationToken) { var unescapedIdentifier = token.ValueText; var enclosingXmlNameAttr = token.GetAncestors(n => n is XmlNameAttributeSyntax).FirstOrDefault(); // always escape keywords if (SyntaxFacts.GetKeywordKind(unescapedIdentifier) != SyntaxKind.None && enclosingXmlNameAttr == null) { return CreateNewIdentifierTokenFromToken(token, escape: true); } // Escape the Await Identifier if within the Single Line Lambda & Multi Line Context // and async method var parent = token.Parent; if (SyntaxFacts.GetContextualKeywordKind(unescapedIdentifier) == SyntaxKind.AwaitKeyword) { var enclosingLambdaExpression = parent.GetAncestorsOrThis(n => (n is SimpleLambdaExpressionSyntax || n is ParenthesizedLambdaExpressionSyntax)).FirstOrDefault(); if (enclosingLambdaExpression != null) { if (enclosingLambdaExpression is SimpleLambdaExpressionSyntax) { if (((SimpleLambdaExpressionSyntax)enclosingLambdaExpression).AsyncKeyword.Kind() == SyntaxKind.AsyncKeyword) { return token; } } if (enclosingLambdaExpression is ParenthesizedLambdaExpressionSyntax) { if (((ParenthesizedLambdaExpressionSyntax)enclosingLambdaExpression).AsyncKeyword.Kind() == SyntaxKind.AsyncKeyword) { return token; } } } var enclosingMethodBlock = parent.GetAncestorsOrThis(n => n is MethodDeclarationSyntax).FirstOrDefault(); if (enclosingMethodBlock != null && ((MethodDeclarationSyntax)enclosingMethodBlock).Modifiers.Any(n => n.Kind() == SyntaxKind.AsyncKeyword)) { return token; } } // within a query all contextual query keywords need to be escaped, even if they appear in a non query context. if (token.GetAncestors(n => n is QueryExpressionSyntax).Any()) { switch (SyntaxFacts.GetContextualKeywordKind(unescapedIdentifier)) { case SyntaxKind.FromKeyword: case SyntaxKind.WhereKeyword: case SyntaxKind.SelectKeyword: case SyntaxKind.GroupKeyword: case SyntaxKind.IntoKeyword: case SyntaxKind.OrderByKeyword: case SyntaxKind.JoinKeyword: case SyntaxKind.LetKeyword: case SyntaxKind.InKeyword: case SyntaxKind.OnKeyword: case SyntaxKind.EqualsKeyword: case SyntaxKind.ByKeyword: case SyntaxKind.AscendingKeyword: case SyntaxKind.DescendingKeyword: return CreateNewIdentifierTokenFromToken(token, escape: true); } } var result = token.Kind() == SyntaxKind.IdentifierToken ? CreateNewIdentifierTokenFromToken(token, escape: false) : token; // we can't remove the escaping if this would change the semantic. This can happen in cases // where there are two attribute declarations one with and and one without the attribute // suffix. if (SyntaxFacts.IsAttributeName(parent)) { var expression = (SimpleNameSyntax)parent; var newExpression = expression.WithIdentifier(result); var speculationAnalyzer = new SpeculationAnalyzer(expression, newExpression, semanticModel, cancellationToken); if (speculationAnalyzer.ReplacementChangesSemantics()) { return CreateNewIdentifierTokenFromToken(token, escape: true); } } // TODO: handle crefs and param names of xml doc comments. // crefs have the same escaping rules than csharp, param names do not allow escaping in Dev11, but // we may want to change that for Roslyn (Bug 17984, " Could treat '@' specially in <param>, <typeparam>, etc") return result; }
private static SyntaxNode GetExpansionTarget(SyntaxToken token) { // get the directly enclosing statement var enclosingStatement = token.GetAncestors(n => n is StatementSyntax).FirstOrDefault(); // see if there's an enclosing lambda expression SyntaxNode possibleLambdaExpression = enclosingStatement == null ? token.GetAncestors(n => n is SimpleLambdaExpressionSyntax || n is ParenthesizedLambdaExpressionSyntax).FirstOrDefault() : null; var enclosingNameMemberCrefOrnull = token.GetAncestors(n => n is NameMemberCrefSyntax).LastOrDefault(); if (enclosingNameMemberCrefOrnull != null) { if (token.Parent is TypeSyntax && token.Parent.Parent is TypeSyntax) { enclosingNameMemberCrefOrnull = null; } } var enclosingXmlNameAttr = token.GetAncestors(n => n is XmlNameAttributeSyntax).FirstOrDefault(); if (enclosingXmlNameAttr != null) { return null; } var enclosingInitializer = token.GetAncestors<EqualsValueClauseSyntax>().FirstOrDefault(); if (enclosingStatement == null && enclosingInitializer != null && enclosingInitializer.Parent is VariableDeclaratorSyntax) { return enclosingInitializer.Value; } var attributeSyntax = token.GetAncestor<AttributeSyntax>(); if (attributeSyntax != null) { return attributeSyntax; } // there seems to be no statement above this one. Let's see if we can at least get an SimpleNameSyntax return enclosingStatement ?? enclosingNameMemberCrefOrnull ?? token.GetAncestors(n => n is SimpleNameSyntax).FirstOrDefault(); }
public static bool UnderValidContext(this SyntaxToken token) { return(token.GetAncestors <SyntaxNode>().Any(n => n.CheckTopLevel(token.Span))); }
private static SyntaxToken SimplifyIdentifierToken( SyntaxToken token, SemanticModel semanticModel, OptionSet optionSet, CancellationToken cancellationToken) { var unescapedIdentifier = token.ValueText; var enclosingXmlNameAttr = token.GetAncestors(n => n is XmlNameAttributeSyntax).FirstOrDefault(); // always escape keywords if (SyntaxFacts.GetKeywordKind(unescapedIdentifier) != SyntaxKind.None && enclosingXmlNameAttr == null) { return(CreateNewIdentifierTokenFromToken(token, escape: true)); } // Escape the Await Identifier if within the Single Line Lambda & Multi Line Context // and async method var parent = token.Parent; if (SyntaxFacts.GetContextualKeywordKind(unescapedIdentifier) == SyntaxKind.AwaitKeyword) { var enclosingLambdaExpression = parent.GetAncestorsOrThis(n => (n is SimpleLambdaExpressionSyntax || n is ParenthesizedLambdaExpressionSyntax)).FirstOrDefault(); if (enclosingLambdaExpression != null) { if (enclosingLambdaExpression is SimpleLambdaExpressionSyntax simpleLambda) { if (simpleLambda.AsyncKeyword.Kind() == SyntaxKind.AsyncKeyword) { return(token); } } if (enclosingLambdaExpression is ParenthesizedLambdaExpressionSyntax parenLamdba) { if (parenLamdba.AsyncKeyword.Kind() == SyntaxKind.AsyncKeyword) { return(token); } } } var enclosingMethodBlock = parent.GetAncestorsOrThis(n => n is MethodDeclarationSyntax).FirstOrDefault(); if (enclosingMethodBlock != null && ((MethodDeclarationSyntax)enclosingMethodBlock).Modifiers.Any(n => n.Kind() == SyntaxKind.AsyncKeyword)) { return(token); } } // within a query all contextual query keywords need to be escaped, even if they appear in a non query context. if (token.GetAncestors(n => n is QueryExpressionSyntax).Any()) { switch (SyntaxFacts.GetContextualKeywordKind(unescapedIdentifier)) { case SyntaxKind.FromKeyword: case SyntaxKind.WhereKeyword: case SyntaxKind.SelectKeyword: case SyntaxKind.GroupKeyword: case SyntaxKind.IntoKeyword: case SyntaxKind.OrderByKeyword: case SyntaxKind.JoinKeyword: case SyntaxKind.LetKeyword: case SyntaxKind.InKeyword: case SyntaxKind.OnKeyword: case SyntaxKind.EqualsKeyword: case SyntaxKind.ByKeyword: case SyntaxKind.AscendingKeyword: case SyntaxKind.DescendingKeyword: return(CreateNewIdentifierTokenFromToken(token, escape: true)); } } var result = token.Kind() == SyntaxKind.IdentifierToken ? CreateNewIdentifierTokenFromToken(token, escape: false) : token; // we can't remove the escaping if this would change the semantic. This can happen in cases // where there are two attribute declarations: one with and one without the attribute // suffix. if (SyntaxFacts.IsAttributeName(parent)) { var expression = (SimpleNameSyntax)parent; var newExpression = expression.WithIdentifier(result); var speculationAnalyzer = new SpeculationAnalyzer(expression, newExpression, semanticModel, cancellationToken); if (speculationAnalyzer.ReplacementChangesSemantics()) { return(CreateNewIdentifierTokenFromToken(token, escape: true)); } } // TODO: handle crefs and param names of xml doc comments. // crefs have the same escaping rules than csharp, param names do not allow escaping in Dev11, but // we may want to change that for Roslyn (Bug 17984, " Could treat '@' specially in <param>, <typeparam>, etc") return(result); }
public static T GetAncestor <T>(this SyntaxToken token, Func <T, bool> predicate) where T : SyntaxNode { return(token.GetAncestors <T>().FirstOrDefault(predicate)); }
public static T GetAncestor <T>(this SyntaxToken token) where T : SyntaxNode { return(token.GetAncestors <T>().FirstOrDefault()); }
public static SyntaxNode GetAncestor(this SyntaxToken token, Func <SyntaxNode, bool> predicate) { return(token.GetAncestors(predicate).FirstOrDefault()); }