Files

425 lines
17 KiB
C#
Raw Permalink Normal View History

2026-08-27 10:56:38 -06:00
using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
public static class SyntaxExtensions
{
internal static ArrowExpressionClauseSyntax? GetExpressionBodySyntax(this CSharpSyntaxNode node)
{
ArrowExpressionClauseSyntax result = null;
switch (node.Kind())
{
case SyntaxKind.ArrowExpressionClause:
result = (ArrowExpressionClauseSyntax)node;
break;
case SyntaxKind.MethodDeclaration:
case SyntaxKind.OperatorDeclaration:
case SyntaxKind.ConversionOperatorDeclaration:
case SyntaxKind.ConstructorDeclaration:
case SyntaxKind.DestructorDeclaration:
result = ((BaseMethodDeclarationSyntax)node).ExpressionBody;
break;
case SyntaxKind.GetAccessorDeclaration:
case SyntaxKind.SetAccessorDeclaration:
case SyntaxKind.AddAccessorDeclaration:
case SyntaxKind.RemoveAccessorDeclaration:
case SyntaxKind.UnknownAccessorDeclaration:
case SyntaxKind.InitAccessorDeclaration:
result = ((AccessorDeclarationSyntax)node).ExpressionBody;
break;
case SyntaxKind.PropertyDeclaration:
result = ((PropertyDeclarationSyntax)node).ExpressionBody;
break;
case SyntaxKind.IndexerDeclaration:
result = ((IndexerDeclarationSyntax)node).ExpressionBody;
break;
default:
ExceptionUtilities.UnexpectedValue((object)node.Kind());
break;
}
return result;
}
public static SyntaxToken NormalizeWhitespace(this SyntaxToken token, string indentation, bool elasticTrivia)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
return SyntaxNormalizer.Normalize(token, indentation, "\r\n", elasticTrivia);
}
internal static SyntaxToken Identifier(this DeclarationExpressionSyntax self)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return ((SingleVariableDesignationSyntax)self.Designation).Identifier;
}
public static SyntaxToken NormalizeWhitespace(this SyntaxToken token, string indentation = " ", string eol = "\r\n", bool elasticTrivia = false)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
return SyntaxNormalizer.Normalize(token, indentation, eol, elasticTrivia);
}
public static SyntaxTriviaList NormalizeWhitespace(this SyntaxTriviaList list, string indentation, bool elasticTrivia)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
return SyntaxNormalizer.Normalize(list, indentation, "\r\n", elasticTrivia);
}
public static SyntaxTriviaList NormalizeWhitespace(this SyntaxTriviaList list, string indentation = " ", string eol = "\r\n", bool elasticTrivia = false)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
return SyntaxNormalizer.Normalize(list, indentation, eol, elasticTrivia);
}
public static SyntaxTriviaList ToSyntaxTriviaList(this IEnumerable<SyntaxTrivia> sequence)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return SyntaxFactory.TriviaList(sequence);
}
internal static XmlNameAttributeElementKind GetElementKind(this XmlNameAttributeSyntax attributeSyntax)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
CSharpSyntaxNode parent = attributeSyntax.Parent;
SyntaxKind syntaxKind = parent.Kind();
SyntaxToken localName;
string valueText;
switch (syntaxKind)
{
case SyntaxKind.XmlEmptyElement:
localName = ((XmlEmptyElementSyntax)parent).Name.LocalName;
valueText = ((SyntaxToken)(ref localName)).ValueText;
break;
case SyntaxKind.XmlElementStartTag:
localName = ((XmlElementStartTagSyntax)parent).Name.LocalName;
valueText = ((SyntaxToken)(ref localName)).ValueText;
break;
default:
throw ExceptionUtilities.UnexpectedValue((object)syntaxKind);
}
if (DocumentationCommentXmlNames.ElementEquals(valueText, "param", false))
{
return XmlNameAttributeElementKind.Parameter;
}
if (DocumentationCommentXmlNames.ElementEquals(valueText, "paramref", false))
{
return XmlNameAttributeElementKind.ParameterReference;
}
if (DocumentationCommentXmlNames.ElementEquals(valueText, "typeparam", false))
{
return XmlNameAttributeElementKind.TypeParameter;
}
if (DocumentationCommentXmlNames.ElementEquals(valueText, "typeparamref", false))
{
return XmlNameAttributeElementKind.TypeParameterReference;
}
throw ExceptionUtilities.UnexpectedValue((object)valueText);
}
internal static bool ReportDocumentationCommentDiagnostics(this SyntaxTree tree)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Invalid comparison between Unknown and I4
return (int)tree.Options.DocumentationMode >= 2;
}
public static SimpleNameSyntax WithIdentifier(this SimpleNameSyntax simpleName, SyntaxToken identifier)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
if (simpleName.Kind() != SyntaxKind.IdentifierName)
{
return ((GenericNameSyntax)simpleName).WithIdentifier(identifier);
}
return ((IdentifierNameSyntax)simpleName).WithIdentifier(identifier);
}
internal static bool IsTypeInContextWhichNeedsDynamicAttribute(this IdentifierNameSyntax typeNode)
{
if (SyntaxFacts.IsInTypeOnlyContext(typeNode))
{
return IsInContextWhichNeedsDynamicAttribute(typeNode);
}
return false;
}
internal static ExpressionSyntax SkipParens(this ExpressionSyntax expression)
{
while (expression.Kind() == SyntaxKind.ParenthesizedExpression)
{
expression = ((ParenthesizedExpressionSyntax)expression).Expression;
}
return expression;
}
internal static bool IsDeconstructionLeft(this ExpressionSyntax node)
{
return node.Kind() switch
{
SyntaxKind.TupleExpression => true,
SyntaxKind.DeclarationExpression => ((DeclarationExpressionSyntax)node).Designation.Kind() == SyntaxKind.ParenthesizedVariableDesignation,
_ => false,
};
}
internal static bool IsDeconstruction(this AssignmentExpressionSyntax self)
{
return self.Left.IsDeconstructionLeft();
}
private static bool IsInContextWhichNeedsDynamicAttribute(CSharpSyntaxNode node)
{
switch (node.Kind())
{
case SyntaxKind.DelegateDeclaration:
case SyntaxKind.BaseList:
case SyntaxKind.SimpleBaseType:
case SyntaxKind.FieldDeclaration:
case SyntaxKind.EventFieldDeclaration:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.OperatorDeclaration:
case SyntaxKind.ConversionOperatorDeclaration:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.EventDeclaration:
case SyntaxKind.IndexerDeclaration:
case SyntaxKind.Parameter:
case SyntaxKind.PrimaryConstructorBaseType:
return true;
case SyntaxKind.Block:
case SyntaxKind.VariableDeclarator:
case SyntaxKind.EqualsValueClause:
case SyntaxKind.Attribute:
case SyntaxKind.TypeParameterConstraintClause:
return false;
default:
if (node.Parent != null)
{
return IsInContextWhichNeedsDynamicAttribute(node.Parent);
}
return false;
}
}
public static IndexerDeclarationSyntax Update(this IndexerDeclarationSyntax syntax, SyntaxList<AttributeListSyntax> attributeLists, SyntaxTokenList modifiers, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken thisKeyword, BracketedParameterListSyntax parameterList, AccessorListSyntax accessorList)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
return syntax.Update(attributeLists, modifiers, type, explicitInterfaceSpecifier, thisKeyword, parameterList, accessorList, null, default(SyntaxToken));
}
public static OperatorDeclarationSyntax Update(this OperatorDeclarationSyntax syntax, SyntaxList<AttributeListSyntax> attributeLists, SyntaxTokenList modifiers, TypeSyntax returnType, SyntaxToken operatorKeyword, SyntaxToken operatorToken, ParameterListSyntax parameterList, BlockSyntax block, SyntaxToken semicolonToken)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
return syntax.Update(attributeLists, modifiers, returnType, operatorKeyword, operatorToken, parameterList, block, null, semicolonToken);
}
public static MethodDeclarationSyntax Update(this MethodDeclarationSyntax syntax, SyntaxList<AttributeListSyntax> attributeLists, SyntaxTokenList modifiers, TypeSyntax returnType, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, TypeParameterListSyntax typeParameterList, ParameterListSyntax parameterList, SyntaxList<TypeParameterConstraintClauseSyntax> constraintClauses, BlockSyntax block, SyntaxToken semicolonToken)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
return syntax.Update(attributeLists, modifiers, returnType, explicitInterfaceSpecifier, identifier, typeParameterList, parameterList, constraintClauses, block, null, semicolonToken);
}
internal static CSharpSyntaxNode? GetContainingDeconstruction(this ExpressionSyntax expr)
{
SyntaxKind syntaxKind = expr.Kind();
if (syntaxKind != SyntaxKind.TupleExpression && syntaxKind != SyntaxKind.DeclarationExpression && syntaxKind != SyntaxKind.IdentifierName)
{
return null;
}
while (true)
{
CSharpSyntaxNode parent = expr.Parent;
if (parent == null)
{
break;
}
switch (parent.Kind())
{
case SyntaxKind.Argument:
{
CSharpSyntaxNode? parent2 = parent.Parent;
if (parent2 == null || parent2.Kind() != SyntaxKind.TupleExpression)
{
return null;
}
break;
}
case SyntaxKind.SimpleAssignmentExpression:
if (((AssignmentExpressionSyntax)parent).Left == expr)
{
return parent;
}
return null;
case SyntaxKind.ForEachVariableStatement:
if (((ForEachVariableStatementSyntax)parent).Variable == expr)
{
return parent;
}
return null;
default:
return null;
}
expr = (TupleExpressionSyntax)parent.Parent;
}
return null;
}
internal static bool IsOutDeclaration(this DeclarationExpressionSyntax p)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
CSharpSyntaxNode? parent = p.Parent;
if (parent != null && parent.Kind() == SyntaxKind.Argument)
{
return ((ArgumentSyntax)p.Parent).RefOrOutKeyword.Kind() == SyntaxKind.OutKeyword;
}
return false;
}
internal static bool IsOutVarDeclaration(this DeclarationExpressionSyntax p)
{
if (p.Designation.Kind() == SyntaxKind.SingleVariableDesignation)
{
return p.IsOutDeclaration();
}
return false;
}
internal static void VisitRankSpecifiers<TArg>(this TypeSyntax type, Action<ArrayRankSpecifierSyntax, TArg> action, in TArg argument)
{
//IL_022b: Unknown result type (might be due to invalid IL or missing references)
//IL_0230: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
//IL_0247: Unknown result type (might be due to invalid IL or missing references)
//IL_024c: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
//IL_01be: Unknown result type (might be due to invalid IL or missing references)
//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
ArrayBuilder<SyntaxNode> instance = ArrayBuilder<SyntaxNode>.GetInstance();
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)type);
while (instance.Count > 0)
{
SyntaxNode val = ArrayBuilderExtensions.Pop<SyntaxNode>(instance);
if (val is ArrayRankSpecifierSyntax arg)
{
action(arg, argument);
continue;
}
type = (TypeSyntax)(object)val;
switch (type.Kind())
{
case SyntaxKind.ArrayType:
{
ArrayTypeSyntax arrayTypeSyntax = (ArrayTypeSyntax)type;
for (int num4 = arrayTypeSyntax.RankSpecifiers.Count - 1; num4 >= 0; num4--)
{
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)arrayTypeSyntax.RankSpecifiers[num4]);
}
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)arrayTypeSyntax.ElementType);
break;
}
case SyntaxKind.NullableType:
{
NullableTypeSyntax nullableTypeSyntax = (NullableTypeSyntax)type;
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)nullableTypeSyntax.ElementType);
break;
}
case SyntaxKind.PointerType:
{
PointerTypeSyntax pointerTypeSyntax = (PointerTypeSyntax)type;
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)pointerTypeSyntax.ElementType);
break;
}
case SyntaxKind.FunctionPointerType:
{
FunctionPointerTypeSyntax functionPointerTypeSyntax = (FunctionPointerTypeSyntax)type;
for (int num3 = functionPointerTypeSyntax.ParameterList.Parameters.Count - 1; num3 >= 0; num3--)
{
TypeSyntax type2 = functionPointerTypeSyntax.ParameterList.Parameters[num3].Type;
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)type2);
}
break;
}
case SyntaxKind.TupleType:
{
TupleTypeSyntax tupleTypeSyntax = (TupleTypeSyntax)type;
for (int num2 = tupleTypeSyntax.Elements.Count - 1; num2 >= 0; num2--)
{
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)tupleTypeSyntax.Elements[num2].Type);
}
break;
}
case SyntaxKind.RefType:
{
RefTypeSyntax refTypeSyntax = (RefTypeSyntax)type;
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)refTypeSyntax.Type);
break;
}
case SyntaxKind.ScopedType:
{
ScopedTypeSyntax scopedTypeSyntax = (ScopedTypeSyntax)type;
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)scopedTypeSyntax.Type);
break;
}
case SyntaxKind.GenericName:
{
GenericNameSyntax genericNameSyntax = (GenericNameSyntax)type;
for (int num = genericNameSyntax.TypeArgumentList.Arguments.Count - 1; num >= 0; num--)
{
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)genericNameSyntax.TypeArgumentList.Arguments[num]);
}
break;
}
case SyntaxKind.QualifiedName:
{
QualifiedNameSyntax qualifiedNameSyntax = (QualifiedNameSyntax)type;
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)qualifiedNameSyntax.Right);
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)qualifiedNameSyntax.Left);
break;
}
case SyntaxKind.AliasQualifiedName:
{
AliasQualifiedNameSyntax aliasQualifiedNameSyntax = (AliasQualifiedNameSyntax)type;
ArrayBuilderExtensions.Push<SyntaxNode>(instance, (SyntaxNode)(object)aliasQualifiedNameSyntax.Name);
break;
}
default:
throw ExceptionUtilities.UnexpectedValue((object)type.Kind());
case SyntaxKind.IdentifierName:
case SyntaxKind.PredefinedType:
case SyntaxKind.OmittedTypeArgument:
break;
}
}
instance.Free();
}
}