private TArgumentSyntax GetArgument(SeparatedSyntaxList <TArgumentSyntax> arguments, int index, ISyntaxFactsService syntaxFactsService) { if (arguments.Count > 4) { return(arguments[index]); } return(arguments.FirstOrDefault( argument => string.Equals(GetArgumentName(argument, syntaxFactsService), StringFormatArguments.ParamsArgumentNames[index], StringComparison.OrdinalIgnoreCase)) ?? arguments[index]); }
/// <summary> /// Returns attribute argument with the specified <paramref name="argumentName"/> /// or <see langword="null"/> if no argument with the <paramref name="argumentName"/> was found. /// </summary> /// <param name="attribute"><see cref="AttributeSyntax"/> to get the argument of.</param> /// <param name="argumentName">Name of argument to get.</param> /// <param name="includeParameters">Determines whether to include arguments with colons in the search.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="attribute"/> is <see langword="null"/>. -or- /// <paramref name="argumentName"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"><paramref name="argumentName"/> cannot be empty or white space only.</exception> public static AttributeArgumentSyntax?GetArgument(this AttributeSyntax attribute, string argumentName, bool includeParameters = false) { if (attribute is null) { throw new ArgumentNullException(nameof(attribute)); } if (argumentName is null) { throw new ArgumentNullException(nameof(argumentName)); } if (string.IsNullOrWhiteSpace(argumentName)) { throw new ArgumentException("Property cannot be empty or white space only!", nameof(argumentName)); } if (attribute.ArgumentList is null) { return(null); } SeparatedSyntaxList <AttributeArgumentSyntax> arguments = attribute.ArgumentList.Arguments; if (!arguments.Any()) { return(null); } Func <AttributeArgumentSyntax, bool> func; if (includeParameters) { func = arg => { if (arg.NameEquals is not null) { return(arg.NameEquals.Name.Identifier.ValueText == argumentName); } return(arg.NameColon is not null && arg.NameColon.Name.Identifier.ValueText == argumentName); }; } else { func = arg => arg.NameEquals is not null && arg.NameEquals.Name.Identifier.ValueText == argumentName; } return(arguments.FirstOrDefault(func)); }
private void TranslateList <T>(ShaderTranslationContext sc, SeparatedSyntaxList <T> list) where T : SyntaxNode { T firstIncrementor = list.FirstOrDefault(); foreach (T es in list) { Type test = es.GetType(); if (es != firstIncrementor) { sc.Source.Append(", "); } sc.Runner.Translate(sc, es); } }
/// <summary> /// Returns attribute argument at the specified <paramref name="position"/> and with the given <paramref name="argumentName"/>. /// <para>If <paramref name="argumentName"/> is <see langword="null"/>, only <paramref name="position"/> is included in the search.</para> /// <para>If no appropriate argument found, returns <see langword="null"/>.</para> /// </summary> /// <param name="attribute"><see cref="AttributeSyntax"/> to get the argument of.</param> /// <param name="position">Position of argument to get.</param> /// <param name="argumentName">Name of the argument to get the location of.</param> /// <exception cref="ArgumentNullException"><paramref name="attribute"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> cannot be less than <c>0</c>.</exception> public static AttributeArgumentSyntax?GetArgument(this AttributeSyntax attribute, int position, string?argumentName = null) { if (attribute is null) { throw new ArgumentNullException(nameof(attribute)); } if (position < 0) { throw new ArgumentOutOfRangeException(nameof(position), "Argument position cannot be less than 0!"); } if (attribute.ArgumentList is null) { return(null); } SeparatedSyntaxList <AttributeArgumentSyntax> arguments = attribute.ArgumentList.Arguments; if (!arguments.Any()) { return(null); } if (string.IsNullOrWhiteSpace(argumentName)) { if (position >= arguments.Count) { return(null); } return(arguments[position]); } if (position < arguments.Count) { AttributeArgumentSyntax arg = arguments[position]; if (arg.GetName() == argumentName) { return(arg); } } return(arguments.FirstOrDefault(arg => arg.GetName() == argumentName)); }
public static async Task ComputeRefactoringAsync(RefactoringContext context, LocalDeclarationStatementSyntax localDeclaration) { VariableDeclarationSyntax declaration = localDeclaration.Declaration; if (declaration == null) { return; } SeparatedSyntaxList <VariableDeclaratorSyntax> variables = declaration.Variables; if (!variables.Any()) { return; } VariableDeclaratorSyntax declarator = variables.FirstOrDefault(f => f.FullSpan.Contains(context.Span)); if (declarator?.Identifier.IsMissing != false) { return; } EqualsValueClauseSyntax initializer = declarator.Initializer; if (initializer?.Value?.IsMissing == false) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(declaration.Type, context.CancellationToken); if (typeSymbol?.IsErrorType() != false) { return; } context.RegisterRefactoring( $"Initialize '{declarator.Identifier.ValueText}' with default value", cancellationToken => RefactorAsync(context.Document, localDeclaration, declarator, typeSymbol, cancellationToken), RefactoringIdentifiers.InitializeLocalWithDefaultValue); }
private static void AnalyzeInitializer(SyntaxNodeAnalysisContext context) { var initializer = (InitializerExpressionSyntax)context.Node; SeparatedSyntaxList <ExpressionSyntax> expressions = initializer.Expressions; ExpressionSyntax first = expressions.FirstOrDefault(); if (first == null) { return; } if (IsExpectedTrailingTrivia(initializer.OpenBraceToken.TrailingTrivia)) { SyntaxTriviaList leading = first.GetLeadingTrivia(); if (leading.Any()) { TextSpan?span = GetEmptyLineSpan(leading, isEnd: false); if (span != null) { ReportDiagnostic(context, span.Value); } } } if (IsExpectedTrailingTrivia(expressions.GetTrailingTrivia())) { SyntaxTriviaList leading = initializer.CloseBraceToken.LeadingTrivia; if (leading.Any()) { TextSpan?span = GetEmptyLineSpan(leading, isEnd: true); if (span != null) { ReportDiagnostic(context, span.Value); } } }
private static void Analyze <TNode>( SyntaxNodeAnalysisContext context, SyntaxNodeOrToken openNodeOrToken, SeparatedSyntaxList <TNode> nodes) where TNode : SyntaxNode { TNode first = nodes.FirstOrDefault(); if (first == null) { return; } TextSpan span = nodes.GetSpan(includeExteriorTrivia: false); if (span.IsSingleLine(first.SyntaxTree)) { SyntaxTriviaList trailing = openNodeOrToken.GetTrailingTrivia(); if (!IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(trailing)) { return; } int indentationLength = GetIncreasedIndentationLength(openNodeOrToken.Parent); if (indentationLength == 0) { return; } if (ShouldFixIndentation(first.GetLeadingTrivia(), indentationLength)) { ReportDiagnostic(); } } else { TextLineCollection lines = null; IndentationAnalysis indentationAnalysis = IndentationAnalysis.Create(openNodeOrToken.Parent); int indentationLength = indentationAnalysis.IncreasedIndentationLength; if (indentationLength == 0) { return; } for (int i = nodes.Count - 1; i >= 0; i--) { SyntaxTriviaList trailing = (i == 0) ? openNodeOrToken.GetTrailingTrivia() : nodes.GetSeparator(i - 1).TrailingTrivia; if (IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(trailing)) { if (ShouldFixIndentation(nodes[i].GetLeadingTrivia(), indentationLength)) { ReportDiagnostic(); break; } } else { if (nodes.Count > 1 && ShouldWrapAndIndent(context.Node, i)) { ReportDiagnostic(); break; } if (nodes.Count == 1 && first.IsKind(SyntaxKind.Argument)) { var argument = (ArgumentSyntax)(SyntaxNode)first; LambdaBlock lambdaBlock = GetLambdaBlock(argument, lines ??= first.SyntaxTree.GetText().Lines); if (lambdaBlock.Block != null) { SyntaxToken token = lambdaBlock.Token; SyntaxTriviaList leading = token.LeadingTrivia; if (leading.Any()) { SyntaxTrivia trivia = leading.Last(); if (trivia.IsWhitespaceTrivia() && trivia.SpanStart == lambdaBlock.LineStartIndex && trivia.Span.Length != indentationAnalysis.IndentationLength) { ReportDiagnostic(); break; } } else if (lambdaBlock.LineStartIndex == token.SpanStart) { ReportDiagnostic(); break; } return; } } if (lines == null) { lines = first.SyntaxTree.GetText().Lines; } int lineIndex = lines.IndexOf(span.Start); if (lineIndex < lines.Count - 1) { int lineStartIndex = lines[lineIndex + 1].Start; if (first.Span.Contains(lineStartIndex)) { SyntaxToken token = first.FindToken(lineStartIndex); if (!token.IsKind(SyntaxKind.None)) { SyntaxTriviaList leading = token.LeadingTrivia; if (leading.Any()) { if (leading.FullSpan.Contains(lineStartIndex)) { SyntaxTrivia trivia = leading.Last(); if (trivia.IsWhitespaceTrivia() && trivia.SpanStart == lineStartIndex && trivia.Span.Length != indentationLength) { ReportDiagnostic(); break; } } } else if (lineStartIndex == token.SpanStart) { ReportDiagnostic(); break; } } } } } } } void ReportDiagnostic() { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticDescriptors.FixFormattingOfList, Location.Create(first.SyntaxTree, nodes.Span), GetTitle()); }
private static async Task <StatementListInfo> RefactorAsync <TStatement>( Document document, TStatement statement, StatementListInfo statementsInfo, Func <TStatement, TStatement> createNewStatement, int count, bool removeReturnStatement, CancellationToken cancellationToken) where TStatement : StatementSyntax { int statementIndex = statementsInfo.IndexOf(statement); var returnStatement = (ReturnStatementSyntax)statementsInfo[statementIndex + 1]; ExpressionSyntax returnExpression = returnStatement.Expression; ExpressionSyntax newReturnExpression = null; SyntaxTriviaList newTrailingTrivia = default; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ISymbol symbol = semanticModel.GetSymbol(returnExpression, cancellationToken); if (symbol.Kind == SymbolKind.Local && statementIndex > 0 && statementsInfo[statementIndex - 1] is LocalDeclarationStatementSyntax localDeclarationStatement && !localDeclarationStatement.ContainsDiagnostics && !localDeclarationStatement.SpanOrTrailingTriviaContainsDirectives() && !statement.GetLeadingTrivia().Any(f => f.IsDirective)) { SeparatedSyntaxList <VariableDeclaratorSyntax> declarators = localDeclarationStatement.Declaration.Variables; VariableDeclaratorSyntax declarator = declarators.FirstOrDefault(f => semanticModel.GetDeclaredSymbol(f, cancellationToken)?.Equals(symbol) == true); if (declarator != null) { ExpressionSyntax value = declarator.Initializer?.Value; if (removeReturnStatement || value != null) { IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync(symbol, document.Solution(), cancellationToken).ConfigureAwait(false); if (referencedSymbols.First().Locations.Count() == count + 1) { newReturnExpression = value; if (declarators.Count == 1) { if (!removeReturnStatement && returnStatement.GetTrailingTrivia().IsEmptyOrWhitespace()) { SyntaxTriviaList trailingTrivia = localDeclarationStatement.GetTrailingTrivia(); if (trailingTrivia .SkipWhile(f => f.IsWhitespaceTrivia()) .FirstOrDefault() .IsKind(SyntaxKind.SingleLineCommentTrivia)) { newTrailingTrivia = trailingTrivia; } } SyntaxRemoveOptions removeOptions = SyntaxRefactorings.GetRemoveOptions(localDeclarationStatement); if (newTrailingTrivia.Any()) { removeOptions &= ~SyntaxRemoveOptions.KeepTrailingTrivia; } statementsInfo = statementsInfo.RemoveNode(localDeclarationStatement, removeOptions); statementIndex--; } else { statementsInfo = statementsInfo.ReplaceNode(localDeclarationStatement, localDeclarationStatement.RemoveNode(declarator, SyntaxRefactorings.GetRemoveOptions(declarator))); } returnStatement = (ReturnStatementSyntax)statementsInfo[statementIndex + 1]; } } } } if (removeReturnStatement) { statementsInfo = statementsInfo.RemoveNode(returnStatement, SyntaxRefactorings.GetRemoveOptions(returnStatement)); } else if (newReturnExpression != null) { ReturnStatementSyntax newReturnStatement = returnStatement.WithExpression(newReturnExpression.WithTriviaFrom(returnExpression)); if (newTrailingTrivia.Any()) { newReturnStatement = newReturnStatement.WithTrailingTrivia(newTrailingTrivia); } statementsInfo = statementsInfo.ReplaceNode(returnStatement, newReturnStatement); } StatementSyntax oldNode = statementsInfo[statementIndex]; TStatement newNode = createNewStatement((TStatement)oldNode).WithFormatterAnnotation(); return(statementsInfo.ReplaceNode(oldNode, newNode)); }
private static ParameterSyntax GetParameterWithIdentifierEqualToStringLiteral(LiteralExpressionSyntax stringLiteral, SeparatedSyntaxList <ParameterSyntax> parameters) => parameters.FirstOrDefault(m => string.Equals(m.Identifier.ValueText, stringLiteral.Token.ValueText, StringComparison.Ordinal));
private static void AnalyzeInitializer(SyntaxNodeAnalysisContext context) { var initializer = (InitializerExpressionSyntax)context.Node; SeparatedSyntaxList <ExpressionSyntax> expressions = initializer.Expressions; ExpressionSyntax first = expressions.FirstOrDefault(); if (first == null) { return; } if (IsExpectedTrailingTrivia(initializer.OpenBraceToken.TrailingTrivia)) { SyntaxTriviaList leading = first.GetLeadingTrivia(); if (leading.Any()) { TextSpan?span = GetEmptyLineSpan(leading, isEnd: false); if (span != null) { ReportDiagnostic(context, span.Value); } } } if (IsExpectedTrailingTrivia(expressions.GetTrailingTrivia())) { SyntaxTriviaList leading = initializer.CloseBraceToken.LeadingTrivia; if (leading.Any()) { TextSpan?span = GetEmptyLineSpan(leading, isEnd: true); if (span != null) { ReportDiagnostic(context, span.Value); } } } bool IsExpectedTrailingTrivia(SyntaxTriviaList triviaList) { foreach (SyntaxTrivia trivia in triviaList) { switch (trivia.Kind()) { case SyntaxKind.WhitespaceTrivia: break; case SyntaxKind.EndOfLineTrivia: return(true); default: return(false); } } return(false); } }
private static ParameterSyntax GetParameterWithIdentifierEqualToStringLiteral(LiteralExpressionSyntax stringLiteral, SeparatedSyntaxList<ParameterSyntax> parameters) => parameters.FirstOrDefault(m => string.Equals(m.Identifier.ValueText, stringLiteral.Token.ValueText, StringComparison.Ordinal));
public static AttributeSyntax GetStepAttribute(this SeparatedSyntaxList <AttributeSyntax> list) { return(list.FirstOrDefault(argumentSyntax => string.CompareOrdinal(argumentSyntax.ToFullString(), LibType.Step.FullName()) > 0)); }
private TArgumentSyntax GetFormatArgument(SeparatedSyntaxList <TArgumentSyntax> arguments, ISyntaxFactsService syntaxFactsService) => arguments.FirstOrDefault(argument => string.Equals(GetArgumentName(argument, syntaxFactsService), StringFormatArguments.FormatArgumentName, StringComparison.OrdinalIgnoreCase)) ?? arguments[0];
/// <summary> /// Returns true if the specified node is of a kind that could represent a closure scope -- that /// is, a scope of a captured variable. /// Doesn't check whether or not the node actually declares any captured variable. /// </summary> internal static bool IsClosureScope(SyntaxNode node) { switch (node.Kind()) { case SyntaxKind.Block: case SyntaxKind.SwitchStatement: case SyntaxKind.ArrowExpressionClause: // expression-bodied member case SyntaxKind.CatchClause: case SyntaxKind.ForStatement: case SyntaxKind.ForEachStatement: case SyntaxKind.ForEachVariableStatement: case SyntaxKind.UsingStatement: // ctor parameter captured by a lambda in a ctor initializer case SyntaxKind.ConstructorDeclaration: return(true); // Due to pattern-matching, any statement that contains an expression may introduce a scope. case SyntaxKind.DoStatement: case SyntaxKind.ExpressionStatement: case SyntaxKind.FixedStatement: case SyntaxKind.GotoCaseStatement: case SyntaxKind.IfStatement: case SyntaxKind.LockStatement: case SyntaxKind.ReturnStatement: case SyntaxKind.ThisConstructorInitializer: case SyntaxKind.BaseConstructorInitializer: case SyntaxKind.ThrowStatement: case SyntaxKind.WhileStatement: case SyntaxKind.YieldReturnStatement: return(true); case SyntaxKind.ClassDeclaration: case SyntaxKind.StructDeclaration: // With dynamic analysis instrumentation, a type declaration can be the syntax associated // with the analysis payload local of a synthesized constructor. // If the synthesized constructor includes an initializer with a lambda, // that lambda needs a closure that captures the analysis payload of the constructor. return(true); default: // With the introduction of pattern-matching, many nodes now contain top-level // expressions that may introduce pattern variables. if (node.Parent != null) { switch (node.Parent.Kind()) { case SyntaxKind.EqualsValueClause: return(true); case SyntaxKind.ForStatement: SeparatedSyntaxList <ExpressionSyntax> incrementors = ((ForStatementSyntax)node.Parent).Incrementors; if (incrementors.FirstOrDefault() == node) { return(true); } break; } } break; } if (IsLambdaBody(node)) { return(true); } // TODO: EE expression if (node is ExpressionSyntax && node.Parent != null && node.Parent.Parent == null) { return(true); } return(false); }
private static async Task <StatementListInfo> RefactorAsync <TStatement>( Document document, TStatement statement, StatementListInfo statementsInfo, Func <TStatement, TStatement> createNewStatement, int count, bool removeReturnStatement, CancellationToken cancellationToken) where TStatement : StatementSyntax { int index = statementsInfo.IndexOf(statement); var returnStatement = (ReturnStatementSyntax)statementsInfo[index + 1]; ExpressionSyntax expression = returnStatement.Expression; ExpressionSyntax newExpression = null; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ISymbol symbol = semanticModel.GetSymbol(expression, cancellationToken); if (symbol.Kind == SymbolKind.Local && index > 0) { var localDeclarationStatement = statementsInfo[index - 1] as LocalDeclarationStatementSyntax; if (localDeclarationStatement?.ContainsDiagnostics == false && !localDeclarationStatement.SpanOrTrailingTriviaContainsDirectives() && !statement.GetLeadingTrivia().Any(f => f.IsDirective)) { SeparatedSyntaxList <VariableDeclaratorSyntax> declarators = localDeclarationStatement.Declaration.Variables; VariableDeclaratorSyntax declarator = declarators.FirstOrDefault(f => semanticModel.GetDeclaredSymbol(f, cancellationToken)?.Equals(symbol) == true); if (declarator != null) { ExpressionSyntax value = declarator.Initializer?.Value; if (removeReturnStatement || value != null) { IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync(symbol, document.Solution(), cancellationToken).ConfigureAwait(false); if (referencedSymbols.First().Locations.Count() == count + 1) { newExpression = value; if (declarators.Count == 1) { statementsInfo = statementsInfo.RemoveNode(localDeclarationStatement, SyntaxRemover.GetRemoveOptions(localDeclarationStatement)); index--; } else { statementsInfo = statementsInfo.ReplaceNode(localDeclarationStatement, localDeclarationStatement.RemoveNode(declarator, SyntaxRemover.GetRemoveOptions(declarator))); } returnStatement = (ReturnStatementSyntax)statementsInfo[index + 1]; } } } } } if (removeReturnStatement) { statementsInfo = statementsInfo.RemoveNode(returnStatement, SyntaxRemover.GetRemoveOptions(returnStatement)); } else if (newExpression != null) { statementsInfo = statementsInfo.ReplaceNode(returnStatement, returnStatement.WithExpression(newExpression.WithTriviaFrom(expression))); } StatementSyntax oldNode = statementsInfo[index]; TStatement newNode = createNewStatement((TStatement)oldNode).WithFormatterAnnotation(); return(statementsInfo.ReplaceNode(oldNode, newNode)); }
public override TNode First() => SyntaxWrapper.Wrap(SyntaxList.FirstOrDefault());