425 lines
17 KiB
C#
425 lines
17 KiB
C#
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();
|
|
}
|
|
}
|