File: SyntaxGeneratorInternal.cs
Web Access
Project: ..\..\..\src\Workspaces\Core\Portable\Microsoft.CodeAnalysis.Workspaces.csproj (Microsoft.CodeAnalysis.Workspaces)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Collections.Generic;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.LanguageService;
using Microsoft.CodeAnalysis.Operations;
 
namespace Microsoft.CodeAnalysis.Editing
{
    /// <summary>
    /// Internal extensions to <see cref="SyntaxGenerator"/>.
    /// 
    /// This interface is available in the shared CodeStyle and Workspaces layer to allow
    /// sharing internal generator methods between them. Once the methods are ready to be
    /// made public APIs, they can be moved to <see cref="SyntaxGenerator"/>.
    /// </summary>
    internal abstract class SyntaxGeneratorInternal : ILanguageService
    {
        public abstract ISyntaxFacts SyntaxFacts { get; }
 
        public abstract SyntaxTrivia EndOfLine(string text);
 
        /// <summary>
        /// Creates a statement that declares a single local variable with an optional initializer.
        /// </summary>
        public abstract SyntaxNode LocalDeclarationStatement(
            SyntaxNode? type, SyntaxToken identifier, SyntaxNode? initializer = null, bool isConst = false);
 
        /// <summary>
        /// Creates a statement that declares a single local variable.
        /// </summary>
        public SyntaxNode LocalDeclarationStatement(SyntaxToken name, SyntaxNode initializer)
            => LocalDeclarationStatement(null, name, initializer);
 
        public abstract SyntaxNode WithInitializer(SyntaxNode variableDeclarator, SyntaxNode initializer);
 
        public abstract SyntaxNode EqualsValueClause(SyntaxToken operatorToken, SyntaxNode value);
 
        public abstract SyntaxToken Identifier(string identifier);
 
        public abstract SyntaxNode ConditionalAccessExpression(SyntaxNode expression, SyntaxNode whenNotNull);
 
        public abstract SyntaxNode MemberBindingExpression(SyntaxNode name);
 
        public abstract SyntaxNode RefExpression(SyntaxNode expression);
 
        /// <summary>
        /// Wraps with parens.
        /// </summary>
        public abstract SyntaxNode AddParentheses(SyntaxNode expression, bool includeElasticTrivia = true, bool addSimplifierAnnotation = true);
 
        /// <summary>
        /// Creates a statement that can be used to yield a value from an iterator method.
        /// </summary>
        /// <param name="expression">An expression that can be yielded.</param>
        public abstract SyntaxNode YieldReturnStatement(SyntaxNode expression);
 
        /// <summary>
        /// <see langword="true"/> if the language requires a "TypeExpression"
        /// (including <see langword="var"/>) to be stated when making a 
        /// <see cref="LocalDeclarationStatement(SyntaxNode, SyntaxToken, SyntaxNode, bool)"/>.
        /// <see langword="false"/> if the language allows the type node to be entirely elided.
        /// </summary>
        public abstract bool RequiresLocalDeclarationType();
 
        public abstract SyntaxToken InterpolatedStringTextToken(string content, string value);
        public abstract SyntaxNode InterpolatedStringText(SyntaxToken textToken);
        public abstract SyntaxNode Interpolation(SyntaxNode syntaxNode);
        public abstract SyntaxNode InterpolatedStringExpression(SyntaxToken startToken, IEnumerable<SyntaxNode> content, SyntaxToken endToken);
        public abstract SyntaxNode InterpolationAlignmentClause(SyntaxNode alignment);
        public abstract SyntaxNode InterpolationFormatClause(string format);
        public abstract SyntaxNode TypeParameterList(IEnumerable<string> typeParameterNames);
 
        /// <summary>
        /// Produces an appropriate TypeSyntax for the given <see cref="ITypeSymbol"/>.  The <paramref name="typeContext"/>
        /// flag controls how this should be created depending on if this node is intended for use in a type-only
        /// context, or an expression-level context.  In the former case, both C# and VB will create QualifiedNameSyntax
        /// nodes for dotted type names, whereas in the latter case both languages will create MemberAccessExpressionSyntax
        /// nodes.  The final stringified result will be the same in both cases.  However, the structure of the trees
        /// will be substantively different, which can impact how the compilation layers analyze the tree and how
        /// transformational passes affect it.
        /// </summary>
        /// <remarks>
        /// Passing in the right value for <paramref name="typeContext"/> is necessary for correctness and for use
        /// of compilation (and other) layers in a supported fashion.  For example, if a QualifiedTypeSyntax is
        /// sed in a place the compiler would have parsed out a MemberAccessExpression, then it is undefined behavior
        /// what will happen if that tree is passed to any other components.
        /// </remarks>
        public abstract SyntaxNode Type(ITypeSymbol typeSymbol, bool typeContext);
 
        public abstract SyntaxNode NegateEquality(SyntaxGenerator generator, SyntaxNode binaryExpression, SyntaxNode left, BinaryOperatorKind negatedKind, SyntaxNode right);
 
        public abstract SyntaxNode IsNotTypeExpression(SyntaxNode expression, SyntaxNode type);
 
        #region Patterns
 
        public abstract bool SupportsPatterns(ParseOptions options);
        public abstract SyntaxNode IsPatternExpression(SyntaxNode expression, SyntaxToken isToken, SyntaxNode pattern);
 
        public abstract SyntaxNode AndPattern(SyntaxNode left, SyntaxNode right);
        public abstract SyntaxNode ConstantPattern(SyntaxNode expression);
        public abstract SyntaxNode DeclarationPattern(INamedTypeSymbol type, string name);
        public abstract SyntaxNode GreaterThanRelationalPattern(SyntaxNode expression);
        public abstract SyntaxNode GreaterThanEqualsRelationalPattern(SyntaxNode expression);
        public abstract SyntaxNode LessThanRelationalPattern(SyntaxNode expression);
        public abstract SyntaxNode LessThanEqualsRelationalPattern(SyntaxNode expression);
        public abstract SyntaxNode NotPattern(SyntaxNode pattern);
        public abstract SyntaxNode OrPattern(SyntaxNode left, SyntaxNode right);
        public abstract SyntaxNode ParenthesizedPattern(SyntaxNode pattern);
        public abstract SyntaxNode TypePattern(SyntaxNode type);
        public abstract SyntaxNode UnaryPattern(SyntaxToken operatorToken, SyntaxNode pattern);
 
        #endregion
    }
}