Microsoft.CodeAnalysis.CSharp.Workspaces Determine the classification type for a given token. The token. The correct syntactic classification for the token. Worker is an utility class that can classify a list of tokens or a tree within a requested span The implementation is generic and can produce any kind of classification artifacts T T is normally either ClassificationSpan or a Tuple (for testing purposes) and constructed via provided factory. Moves the trailing trivia from the node's previous token to the end of the node Try use the existing syntax node and generate a new syntax node for the given . Note: the returned syntax node might be modified, which means its parent information might be missing. C# always requires a type to be present with a local declaration. (Even if that type is var). Parenthesize the left hand size of a member access, invocation or element access expression Builds up the suffix to show for something with parameters in navigate-to. While it would be nice to just use the compiler SymbolDisplay API for this, it would be too expensive as it requires going back to Symbols (which requires creating compilations, etc.) in a perf sensitive area. So, instead, we just build a reasonable suffix using the pure syntax that a user provided. That means that if they wrote "Method(System.Int32 i)" we'll show that as "Method(System.Int32)" not "Method(int)". Given that this is actually what the user wrote, and it saves us from ever having to go back to symbols/compilations, this is well worth it, even if it does mean we have to create our own 'symbol display' logic here. We'll autoformat on 'n', 't', 'e', only if they are the last character of the below keywords. Internal option -- not exposed to editorconfig tooling via . Options that we expect the user to set in editorconfig. Options that can be set via editorconfig but we do not provide tooling support. Placed in the Zeroth column of the text editor Placed at one less indent to the current context Placed at the same indent as the current context Single Spacing Ignore Formatting Remove Spacing this holds onto changes made by formatting engine. C# never passes a VB Comment trivia factory. it will cache some commonly used trivia to reduce memory footprint and heap allocation represents a general trivia between two tokens. slightly more expensive than others since it needs to calculate stuff unlike other cases Checks whether currentToken is the opening paren of a deconstruction-declaration in var form, such as var (x, y) = ... Check whether the currentToken is a comma and is a delimiter between arguments inside a tuple expression. Adds user defined and predefined conversions to the unnamed recommendation set. Adds user defined operators to the unnamed recommendation set. Flag indicating if we should perform a rename inside string literals. Flag indicating if we should perform a rename inside comment trivia. A map from spans of tokens needing rename within strings or comments to an optional set of specific sub-spans within the token span that have matches and should be renamed. If this sorted set is null, it indicates that sub-spans to rename within the token span are not available, and a regex match should be performed to rename all matches within the span. Gets the top most enclosing statement or CrefSyntax as target to call MakeExplicit on. It's either the enclosing statement, or if this statement is inside of a lambda expression, the enclosing statement of this lambda. The token to get the complexification target for. Gets the semantic model for the given node. If the node belongs to the syntax tree of the original semantic model, then returns originalSemanticModel. Otherwise, returns a speculative model. The assumption for the later case is that span start position of the given node in it's syntax tree is same as the span start of the original node in the original syntax tree. Computes a list of nodes and tokens that need to be reduced in the given syntax root. Complexify makes inferred names explicit for tuple elements and anonymous type members. This class considers which ones of those can be simplified (after the refactoring was done). If the inferred name of the member matches, the explicit name (from Complexify) can be removed. Contains helpers used by several simplifier subclasses. Returns the predefined keyword kind for a given . The of this type. The keyword kind for a given special type, or SyntaxKind.None if the type name is not a predefined type. Compares symbols by their original definition. Determines if and together contain a superset of the symbols in . Tells if the member access is dynamically invoked and cannot be reduced. In the case of NS1.NS2.T1.T2.Method(...dynamic...) we can only remove the NS1.NS2 portion. The namespace part is not encoded into the IL, but the specific types in T1.T2 and cannot be removed. Checks if the SyntaxNode is a name of a namespace declaration. To be a namespace name, the syntax must be parented by an namespace declaration and the node itself must be equal to the declaration's Name property. By default the cast simplifier operates under several main principles: The final type that a cast-expression was converted to should be the same as the final type that the underlying expression should convert to without the cast. This tells us that the compiler thinks that value should convert to that type implicitly, not just explicitly. Static semantics of the code should remain the same. This means that things like overload resolution of the invocations the casted expression is contained within should not change. Runtime types and values should not observably change. This means that if casting the value would cause a different type to be seen in a call, or a different value could be observed at runtime, then it must remain. These rules serve as a good foundational intuition about when casts should be kept and when they should be removable. However, they are not entirely complete. There are cases when we can weaken some of the above rules if it would not be observable at runtime. For example, if it can be proven that calling through an interface method would lead to the exact same call at runtime to a specific implementation of that interface method, then it can be legal to remove such a cast as at runtime this would not be observable. This does in effect mean that the emitted IL will be different, but this matches the user expectation that the *end* behavior of their code remains the same. Parsed that creates with given encoding and checksum algorithm. Options that we expect the user to set in editorconfig. Analyzes if type information is obvious to the reader by simply looking at the assignment expression. accepts null, to be able to cater to codegen features that are about to generate a local declaration and do not have this information to pass in. Things (like analyzers) that do have a local declaration already, should pass this in. Looks for types that have static methods that return the same type as the container. e.g: int.Parse, XElement.Load, Tuple.Create etc. If we have a method ToXXX and its return type is also XXX, then type name is apparent e.g: Convert.ToString. Creates the sequence for the content characters in this . This will not include indentation whitespace that the language specifies is not part of the content. The containing expression for this token. This is needed so that we can determine the indentation whitespace based on the last line of the containing multiline literal. If this token includes the quote (") characters for the delimiters inside of it or not. If so, then those quotes will need to be skipped when determining the content Returns the parameter to which this argument is passed. If is true, the last parameter will be returned if it is params parameter and the index of the specified argument is greater than the number of parameters. Returns the parameter to which this argument is passed. If is true, the last parameter will be returned if it is params parameter and the index of the specified argument is greater than the number of parameters. Returns null if the is a named argument. Are you possibly typing a tuple type or expression? This is used to suppress colon as a completion trigger (so that you can type element names). This is also used to recommend some keywords (like var). Are you possibly in the designation part of a deconstruction? This is used to enter suggestion mode (suggestions become soft-selected). If inside a parenthesized or tuple expression, unwrap the nestings and return the container. Is this a possible position for an await statement (`await using` or `await foreach`)? Determines whether await should be suggested in a given position. Returns true if this expression is in some ref keyword context. If then will be the node containing the keyword. If this declaration or identifier is part of a deconstruction, find the deconstruction. If found, returns either an assignment expression or a foreach variable statement. Returns null otherwise. copied from SyntaxExtensions.GetContainingDeconstruction Adds to if it does not contain an anonymous type and binds to the same type at the given . DeterminesCheck if we're in an interesting situation like this: int i = 5; i. // -- here List ml = new List(); The problem is that "i.List" gets parsed as a type. In this case we need to try binding again as if "i" is an expression and not a type. In order to do that, we need to speculate as to what 'i' meant if it wasn't part of a local declaration's type. Another interesting case is something like: stringList. await Test2(); Here "stringList.await" is thought of as the return type of a local function. if only normal name-syntax nodes should be returned. if special nodes (like predefined types) can be used. We always unilaterally add "global::" to all named types/namespaces. This will then be trimmed off if possible by the simplifier. Operator precedence classes from section 7.3.1 of the C# language specification. Decomposes a name or member access expression into its component parts. The name or member access expression. The qualifier (or left-hand-side) of the name expression. This may be null if there is no qualifier. The name of the expression. The number of generic type parameters. Given an expression node, tries to generate an appropriate name that can be used for that expression. Returns whether or not and are exactly identical to and respectively. Given an argument node, tries to generate an appropriate name that can be used for that argument. Determine if the given array contains the given kind. Array to search Sought value True if contains the value. PERF: Not using Array.IndexOf here because it results in a call to IndexOf on the default EqualityComparer for SyntaxKind.The default comparer for SyntaxKind is the ObjectEqualityComparer which results in boxing allocations. Returns all of the trivia to the left of this token up to the previous token (concatenates the previous token's trailing trivia and this token's leading trivia). > Returns the list of using directives that affect . The list will be returned in top down order. Returns true if the passed in node contains an interleaved pp directive. i.e. The following returns false: void Goo() { #if true #endif } #if true void Goo() { } #endif but these return true: #if true void Goo() { #endif } void Goo() { #if true } #endif #if true void Goo() { #else } #endif i.e. the method returns true if it contains a PP directive that belongs to a grouping constructs (like #if/#endif or #region/#endregion), but the grouping construct isn't entirely contained within the span of the node. Similar to except that the span to check for interleaved directives can be specified separately to the node passed in. Breaks up the list of provided nodes, based on how they are interspersed with pp directives, into groups. Within these groups nodes can be moved around safely, without breaking any pp constructs. Returns true if this token is something that looks like a C# keyword. This includes actual keywords, contextual keywords, and even 'var' and 'dynamic' Determines whether the given SyntaxToken is the first token on a line in the specified SourceText. Retrieves all trivia after this token, including it's trailing trivia and the leading trivia of the next token. Lexically, find the last token that looks like it's part of this generic name. The "name" of the generic identifier, last token before the "&" The last token in the name This is related to the code in SyntaxTreeExtensions.IsInPartiallyWrittenGeneric Takes an INCLUSIVE range of trivia from the trivia list. Determines whether the specified TypeSyntax is actually 'var'. Available if is or . Available if is or . Available if is or . Corresponds to Microsoft.CodeAnalysis.CSharp.LanguageVersionFacts.CSharpNext. Returns the best symbols found that the provided token binds to. This is similar to , but sometimes employs heuristics to provide a better result for tokens that users conceptually think bind to things, but which the compiler does not necessarily return results for. this help finding a range of tokens to format based on given ending token Helper class to analyze the semantic effects of a speculated syntax node replacement on the parenting nodes. Given an expression node from a syntax tree and a new expression from a different syntax tree, it replaces the expression with the new expression to create a speculated syntax tree. It uses the original tree's semantic model to create a speculative semantic model and verifies that the syntax replacement doesn't break the semantics of any parenting nodes of the original expression. Creates a semantic analyzer for speculative syntax replacement. Original expression to be replaced. New expression to replace the original expression. Semantic model of node's syntax tree. Cancellation token. True if semantic analysis should be skipped for the replaced node and performed starting from parent of the original and replaced nodes. This could be the case when custom verifications are required to be done by the caller or semantics of the replaced expression are different from the original expression. True if semantic analysis should fail when any of the invocation expression ancestors of in original code has overload resolution failures. Determines whether performing the syntax replacement in one of the sibling nodes of the given lambda expressions will change the lambda binding semantics. This is done by first determining the lambda parameters whose type differs in the replaced lambda node. For each of these parameters, we find the descendant identifier name nodes in the lambda body and check if semantics of any of the parenting nodes of these identifier nodes have changed in the replaced lambda. Checks if the conversion might change the resultant boxed type. Similar boxing checks are performed elsewhere, but in this case we need to perform the check on the entire conditional expression. This will make sure the resultant cast is proper for the type of the conditional expression. Whether or not converting would transition the code to the style the user prefers. i.e. if the user likes var for everything, and you have int i = 0 then will be . However, if the user likes var for everything and you have var i = 0, then it's still possible to convert that, it would just be for because it goes against the user's preferences. In general, most features should only convert the type if is . The one exception is the refactoring, which is explicitly there to still let people convert things quickly, even if it's going against their stated style. Returns true if type information could be gleaned by simply looking at the given statement. This typically means that the type name occurs in right hand side of an assignment. checks if the type represented by the given symbol is one of the simple types defined in the compiler. From the IDE perspective, we also include object and string to be simplified to var. considers string and object but the compiler's implementation of IsIntrinsicType does not. Returns true for type that are arrays/nullable/pointer types of special types Analyzes the assignment expression and rejects a given declaration if it is unsuitable for explicit typing. false, if explicit typing cannot be used. true, otherwise. Analyzes the assignment expression and rejects a given declaration if it is unsuitable for implicit typing. false, if implicit typing cannot be used. true, otherwise. Walks the portion of the tree we're adding imports to looking to see if those imports could likely cause conflicts with existing code. Note: this is a best-effort basis, and the goal is to catch reasonable conflicts effectively. There may be cases that do slip through that we can adjust for in the future. Those cases should be assessed to see how reasonable/likely they are. I.e. if it's just a hypothetical case with no users being hit, then that's far less important than if we have a reasonable coding pattern that would be impacted by adding an import to a normal namespace. A mapping containing the simple names and arity of all imported types, mapped to the import that they're brought in by. A mapping containing the simple names of all imported extension methods, mapped to the import that they're brought in by. This doesn't keep track of arity because methods can be called with type arguments. We could consider adding more information here (for example the min/max number of args that this can be called with). That could then be used to check if there could be a conflict. However, that's likely more complexity than we need currently. But it is always something we can do in the future. Only attributes, constructor initializers, expressions or statements can be made explicit Implement Interface R&emove and Sort Usings &Sort Usings C# Formatting Rules C# Coding Conventions var preferences Expression-bodied members Pattern matching preferences Null-checking preferences Code-block preferences 'using' directive preferences Expected string or char literal EditorConfig option '{0}' contains unrecognized value '{1}' Indentation preferences Space preferences Wrapping preferences Remove this value when another is added. Defines the known values for . Braces are allowed, but not preferred. The value 0 is important for serialization compatibility in . Prior to the use of this enum, the serialized value was the value . Braces are preferred where allowed except in the following limited situations: Braces are not required for the embedded statement of an else clause when the embedded statement is an if statement. In a sequence of consecutive using statements, only the last statement requires braces. In a sequence of consecutive lock statements, only the last statement requires braces. In a sequence of consecutive fixed statements, only the last statement requires braces. The value 1 is important for serialization compatibility in . Prior to the use of this enum, the serialized value was the value . Braces are always allowed, and generally preferred except in limited situations involving single-line statements and expressions: Braces may be omitted in the cases described for . Braces may be omitted when the entire statement is placed on one line. For a statement that contains one or more embedded statements, braces may be omitted when every embedded statement fits on one line, and the part preceding the embedded statement is placed on one line. If any embedded statement uses braces, braces are preferred for all embedded statements of the same parent statement. For the purposes of evaluating this rule, if the embedded statement following an else keyword is an if statement, the embedded statements of the nested if statement are treated as children of the parent statement of the else keyword.