コード例 #1
0
        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]);
        }
コード例 #2
0
        /// <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));
        }
コード例 #3
0
        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);
            }
        }
コード例 #4
0
        /// <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));
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
                    }
                }
            }
コード例 #7
0
        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));
        }
コード例 #9
0
 private static ParameterSyntax GetParameterWithIdentifierEqualToStringLiteral(LiteralExpressionSyntax stringLiteral, SeparatedSyntaxList <ParameterSyntax> parameters) =>
 parameters.FirstOrDefault(m => string.Equals(m.Identifier.ValueText, stringLiteral.Token.ValueText, StringComparison.Ordinal));
コード例 #10
0
        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);
            }
        }
コード例 #11
0
 private static ParameterSyntax GetParameterWithIdentifierEqualToStringLiteral(LiteralExpressionSyntax stringLiteral, SeparatedSyntaxList<ParameterSyntax> parameters) =>
     parameters.FirstOrDefault(m => string.Equals(m.Identifier.ValueText, stringLiteral.Token.ValueText, StringComparison.Ordinal));
コード例 #12
0
 public static AttributeSyntax GetStepAttribute(this SeparatedSyntaxList <AttributeSyntax> list)
 {
     return(list.FirstOrDefault(argumentSyntax =>
                                string.CompareOrdinal(argumentSyntax.ToFullString(), LibType.Step.FullName()) > 0));
 }
コード例 #13
0
 private TArgumentSyntax GetFormatArgument(SeparatedSyntaxList <TArgumentSyntax> arguments, ISyntaxFactsService syntaxFactsService)
 => arguments.FirstOrDefault(argument => string.Equals(GetArgumentName(argument, syntaxFactsService), StringFormatArguments.FormatArgumentName, StringComparison.OrdinalIgnoreCase)) ?? arguments[0];
コード例 #14
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);
        }
コード例 #15
0
        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));
        }
コード例 #16
0
 public override TNode First()
 => SyntaxWrapper.Wrap(SyntaxList.FirstOrDefault());