Files

525 lines
26 KiB
C#
Raw Permalink Normal View History

2026-08-27 10:56:38 -06:00
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using Microsoft.Cci;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Collections;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
internal sealed class CodeCoverageInstrumenter : CompoundInstrumenter
{
private readonly MethodSymbol _method;
private readonly BoundStatement _methodBody;
private readonly MethodSymbol _createPayloadForMethodsSpanningSingleFile;
private readonly MethodSymbol _createPayloadForMethodsSpanningMultipleFiles;
private readonly ArrayBuilder<SourceSpan> _spansBuilder;
private ImmutableArray<SourceSpan> _dynamicAnalysisSpans = ImmutableArray<SourceSpan>.Empty;
private readonly BoundStatement? _methodEntryInstrumentation;
private readonly ArrayTypeSymbol _payloadType;
private readonly LocalSymbol _methodPayload;
private readonly BindingDiagnosticBag _diagnostics;
private readonly DebugDocumentProvider _debugDocumentProvider;
private readonly SyntheticBoundNodeFactory _methodBodyFactory;
public ImmutableArray<SourceSpan> DynamicAnalysisSpans => _dynamicAnalysisSpans;
public static bool TryCreate(MethodSymbol method, BoundStatement methodBody, SyntheticBoundNodeFactory methodBodyFactory, BindingDiagnosticBag diagnostics, DebugDocumentProvider debugDocumentProvider, Instrumenter previous, [NotNullWhen(true)] out CodeCoverageInstrumenter? instrumenter)
{
instrumenter = null;
if (method.IsImplicitlyDeclared && !method.IsImplicitConstructor)
{
return false;
}
if (IsExcludedFromCodeCoverage(method))
{
return false;
}
MethodSymbol createPayloadOverload = GetCreatePayloadOverload(methodBodyFactory.Compilation, (WellKnownMember)354, methodBody.Syntax, diagnostics);
MethodSymbol createPayloadOverload2 = GetCreatePayloadOverload(methodBodyFactory.Compilation, (WellKnownMember)355, methodBody.Syntax, diagnostics);
if ((object)createPayloadOverload == null || (object)createPayloadOverload2 == null)
{
return false;
}
if (method.Equals(createPayloadOverload) || method.Equals(createPayloadOverload2))
{
return false;
}
instrumenter = new CodeCoverageInstrumenter(method, methodBody, methodBodyFactory, createPayloadOverload, createPayloadOverload2, diagnostics, debugDocumentProvider, previous);
return true;
}
private CodeCoverageInstrumenter(MethodSymbol method, BoundStatement methodBody, SyntheticBoundNodeFactory methodBodyFactory, MethodSymbol createPayloadForMethodsSpanningSingleFile, MethodSymbol createPayloadForMethodsSpanningMultipleFiles, BindingDiagnosticBag diagnostics, DebugDocumentProvider debugDocumentProvider, Instrumenter previous)
: base(previous)
{
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
_createPayloadForMethodsSpanningSingleFile = createPayloadForMethodsSpanningSingleFile;
_createPayloadForMethodsSpanningMultipleFiles = createPayloadForMethodsSpanningMultipleFiles;
_method = method;
_methodBody = methodBody;
_spansBuilder = ArrayBuilder<SourceSpan>.GetInstance();
TypeSymbol typeSymbol = methodBodyFactory.SpecialType((SpecialType)7);
_payloadType = ArrayTypeSymbol.CreateCSharpArray(methodBodyFactory.Compilation.Assembly, TypeWithAnnotations.Create(typeSymbol));
_diagnostics = diagnostics;
_debugDocumentProvider = debugDocumentProvider;
_methodBodyFactory = methodBodyFactory;
MethodSymbol currentFunction = methodBodyFactory.CurrentFunction;
methodBodyFactory.CurrentFunction = method;
_methodPayload = methodBodyFactory.SynthesizedLocal(_payloadType, methodBody.Syntax, isPinned: false, isKnownToReferToTempIfReferenceType: false, (RefKind)0, (SynthesizedLocalKind)34);
SyntaxNode val = MethodDeclarationIfAvailable(methodBody.Syntax);
if (!method.IsImplicitlyDeclared && !(method is SynthesizedSimpleProgramEntryPointSymbol))
{
_methodEntryInstrumentation = AddAnalysisPoint(val, SkipAttributes(val), methodBodyFactory);
}
methodBodyFactory.CurrentFunction = currentFunction;
}
protected override CompoundInstrumenter WithPreviousImpl(Instrumenter previous)
{
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Lowering/Instrumentation/CodeCoverageInstrumenter.cs", 139);
}
private static bool IsExcludedFromCodeCoverage(MethodSymbol method)
{
NamedTypeSymbol containingType = method.ContainingType;
while ((object)containingType != null)
{
if (containingType.IsDirectlyExcludedFromCodeCoverage)
{
return true;
}
containingType = containingType.ContainingType;
}
if ((object)method != null)
{
if (method.IsDirectlyExcludedFromCodeCoverage)
{
return true;
}
Symbol associatedSymbol = method.AssociatedSymbol;
if (associatedSymbol is PropertySymbol propertySymbol)
{
if (propertySymbol.IsDirectlyExcludedFromCodeCoverage)
{
return true;
}
}
else if (associatedSymbol is EventSymbol { IsDirectlyExcludedFromCodeCoverage: not false })
{
return true;
}
}
return false;
}
private static BoundExpressionStatement GetCreatePayloadStatement(ImmutableArray<SourceSpan> dynamicAnalysisSpans, SyntaxNode methodBodySyntax, LocalSymbol methodPayload, MethodSymbol createPayloadForMethodsSpanningSingleFile, MethodSymbol createPayloadForMethodsSpanningMultipleFiles, BoundExpression mvid, BoundExpression methodToken, BoundExpression payloadSlot, SyntheticBoundNodeFactory methodBodyFactory, DebugDocumentProvider debugDocumentProvider)
{
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
MethodSymbol method;
BoundExpression boundExpression;
if (dynamicAnalysisSpans.IsEmpty)
{
method = createPayloadForMethodsSpanningSingleFile;
DebugSourceDocument sourceDocument = GetSourceDocument(debugDocumentProvider, methodBodySyntax);
boundExpression = methodBodyFactory.SourceDocumentIndex(sourceDocument);
}
else
{
PooledHashSet<DebugSourceDocument> instance = PooledHashSet<DebugSourceDocument>.GetInstance();
ArrayBuilder<BoundExpression> instance2 = ArrayBuilder<BoundExpression>.GetInstance();
ImmutableArray<SourceSpan>.Enumerator enumerator = dynamicAnalysisSpans.GetEnumerator();
while (enumerator.MoveNext())
{
DebugSourceDocument document = enumerator.Current.Document;
if (((HashSet<DebugSourceDocument>)(object)instance).Add(document))
{
instance2.Add(methodBodyFactory.SourceDocumentIndex(document));
}
}
instance.Free();
if (instance2.Count == 1)
{
method = createPayloadForMethodsSpanningSingleFile;
boundExpression = ((IEnumerable<BoundExpression>)instance2).Single();
}
else
{
method = createPayloadForMethodsSpanningMultipleFiles;
boundExpression = methodBodyFactory.Array(methodBodyFactory.SpecialType((SpecialType)13), instance2.ToImmutable());
}
instance2.Free();
}
return methodBodyFactory.Assignment(methodBodyFactory.Local(methodPayload), methodBodyFactory.Call(null, method, mvid, methodToken, boundExpression, payloadSlot, methodBodyFactory.Literal(dynamicAnalysisSpans.Length)));
}
public override void InstrumentBlock(BoundBlock original, LocalRewriter rewriter, ref TemporaryArray<LocalSymbol> additionalLocals, out BoundStatement? prologue, out BoundStatement? epilogue, out BoundBlockInstrumentation? instrumentation)
{
base.InstrumentBlock(original, rewriter, ref additionalLocals, out BoundStatement prologue2, out epilogue, out instrumentation);
if (original != rewriter.CurrentMethodBody)
{
prologue = prologue2;
return;
}
_dynamicAnalysisSpans = _spansBuilder.ToImmutableAndFree();
ArrayTypeSymbol payloadType = ArrayTypeSymbol.CreateCSharpArray(_methodBodyFactory.Compilation.Assembly, TypeWithAnnotations.Create(_payloadType));
BoundStatement boundStatement = _methodBodyFactory.Assignment(_methodBodyFactory.Local(_methodPayload), _methodBodyFactory.ArrayAccess(_methodBodyFactory.InstrumentationPayloadRoot(0, payloadType), ImmutableArray.Create(_methodBodyFactory.MethodDefIndex(_method))));
BoundExpression mvid = _methodBodyFactory.ModuleVersionId();
BoundExpression methodToken = _methodBodyFactory.MethodDefIndex(_method);
BoundExpression payloadSlot = _methodBodyFactory.ArrayAccess(_methodBodyFactory.InstrumentationPayloadRoot(0, payloadType), ImmutableArray.Create(_methodBodyFactory.MethodDefIndex(_method)));
BoundStatement createPayloadStatement = GetCreatePayloadStatement(_dynamicAnalysisSpans, _methodBody.Syntax, _methodPayload, _createPayloadForMethodsSpanningSingleFile, _createPayloadForMethodsSpanningMultipleFiles, mvid, methodToken, payloadSlot, _methodBodyFactory, _debugDocumentProvider);
BoundExpression condition = _methodBodyFactory.Binary(BinaryOperatorKind.ObjectEqual, _methodBodyFactory.SpecialType((SpecialType)7), _methodBodyFactory.Local(_methodPayload), _methodBodyFactory.Null(_payloadType));
BoundStatement boundStatement2 = _methodBodyFactory.If(condition, createPayloadStatement);
additionalLocals.Add(_methodPayload);
ArrayBuilder<BoundStatement> instance = ArrayBuilder<BoundStatement>.GetInstance(2 + ((_methodEntryInstrumentation != null) ? 1 : 0) + ((prologue2 != null) ? 1 : 0));
instance.Add(boundStatement);
instance.Add(boundStatement2);
if (_methodEntryInstrumentation != null)
{
instance.Add(_methodEntryInstrumentation);
}
if (prologue2 != null)
{
instance.Add(prologue2);
}
prologue = _methodBodyFactory.StatementList(instance.ToImmutableAndFree());
}
public override BoundStatement InstrumentNoOpStatement(BoundNoOpStatement original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentNoOpStatement(original, rewritten));
}
public override BoundStatement InstrumentBreakStatement(BoundBreakStatement original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentBreakStatement(original, rewritten));
}
public override BoundStatement InstrumentContinueStatement(BoundContinueStatement original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentContinueStatement(original, rewritten));
}
public override BoundStatement InstrumentExpressionStatement(BoundExpressionStatement original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentExpressionStatement(original, rewritten));
}
public override BoundStatement InstrumentFieldOrPropertyInitializer(BoundStatement original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentFieldOrPropertyInitializer(original, rewritten));
}
public override BoundStatement InstrumentGotoStatement(BoundGotoStatement original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentGotoStatement(original, rewritten));
}
public override BoundStatement InstrumentThrowStatement(BoundThrowStatement original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentThrowStatement(original, rewritten));
}
public override BoundStatement InstrumentYieldBreakStatement(BoundYieldBreakStatement original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentYieldBreakStatement(original, rewritten));
}
public override BoundStatement InstrumentYieldReturnStatement(BoundYieldReturnStatement original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentYieldReturnStatement(original, rewritten));
}
public override BoundStatement InstrumentForEachStatementIterationVarDeclaration(BoundForEachStatement original, BoundStatement iterationVarDecl)
{
return AddDynamicAnalysis(original, base.InstrumentForEachStatementIterationVarDeclaration(original, iterationVarDecl));
}
public override BoundStatement InstrumentForEachStatementDeconstructionVariablesDeclaration(BoundForEachStatement original, BoundStatement iterationVarDecl)
{
return AddDynamicAnalysis(original, base.InstrumentForEachStatementDeconstructionVariablesDeclaration(original, iterationVarDecl));
}
public override BoundStatement InstrumentIfStatement(BoundIfStatement original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentIfStatement(original, rewritten));
}
public override BoundStatement InstrumentWhileStatementConditionalGotoStartOrBreak(BoundWhileStatement original, BoundStatement ifConditionGotoStart)
{
return AddDynamicAnalysis(original, base.InstrumentWhileStatementConditionalGotoStartOrBreak(original, ifConditionGotoStart));
}
public override BoundStatement InstrumentUserDefinedLocalInitialization(BoundLocalDeclaration original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentUserDefinedLocalInitialization(original, rewritten));
}
public override BoundStatement InstrumentLockTargetCapture(BoundLockStatement original, BoundStatement lockTargetCapture)
{
return AddDynamicAnalysis(original, base.InstrumentLockTargetCapture(original, lockTargetCapture));
}
public override BoundStatement InstrumentReturnStatement(BoundReturnStatement original, BoundStatement rewritten)
{
rewritten = base.InstrumentReturnStatement(original, rewritten);
if (ReturnsValueWithinExpressionBodiedConstruct(original))
{
return CollectDynamicAnalysis(original, rewritten);
}
return AddDynamicAnalysis(original, rewritten);
}
private static bool ReturnsValueWithinExpressionBodiedConstruct(BoundReturnStatement returnStatement)
{
if (returnStatement.WasCompilerGenerated && returnStatement.ExpressionOpt != null && returnStatement.ExpressionOpt.Syntax != null)
{
SyntaxKind syntaxKind = returnStatement.ExpressionOpt.Syntax.Parent.Kind();
if (syntaxKind - 8642 <= SyntaxKind.List || syntaxKind == SyntaxKind.ArrowExpressionClause)
{
return true;
}
}
return false;
}
public override BoundStatement InstrumentSwitchStatement(BoundSwitchStatement original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentSwitchStatement(original, rewritten));
}
public override BoundStatement InstrumentSwitchWhenClauseConditionalGotoBody(BoundExpression original, BoundStatement ifConditionGotoBody)
{
ifConditionGotoBody = base.InstrumentSwitchWhenClauseConditionalGotoBody(original, ifConditionGotoBody);
WhenClauseSyntax whenClauseSyntax = original.Syntax.FirstAncestorOrSelf<WhenClauseSyntax>((Func<WhenClauseSyntax, bool>)null, true);
SyntheticBoundNodeFactory syntheticBoundNodeFactory = new SyntheticBoundNodeFactory(_method, (SyntaxNode)(object)whenClauseSyntax, _methodBodyFactory.CompilationState, _diagnostics);
return syntheticBoundNodeFactory.StatementList(AddAnalysisPoint((SyntaxNode)(object)whenClauseSyntax, syntheticBoundNodeFactory), ifConditionGotoBody);
}
public override BoundStatement InstrumentUsingTargetCapture(BoundUsingStatement original, BoundStatement usingTargetCapture)
{
return AddDynamicAnalysis(original, base.InstrumentUsingTargetCapture(original, usingTargetCapture));
}
private BoundStatement AddDynamicAnalysis(BoundStatement original, BoundStatement rewritten)
{
if (!original.WasCompilerGenerated && (!original.IsConstructorInitializer() || original.Syntax.Kind() != SyntaxKind.ConstructorDeclaration))
{
return CollectDynamicAnalysis(original, rewritten);
}
return rewritten;
}
private BoundStatement CollectDynamicAnalysis(BoundStatement original, BoundStatement rewritten)
{
SyntheticBoundNodeFactory syntheticBoundNodeFactory = new SyntheticBoundNodeFactory(_method, original.Syntax, _methodBodyFactory.CompilationState, _diagnostics);
return syntheticBoundNodeFactory.StatementList(AddAnalysisPoint(SyntaxForSpan(original), syntheticBoundNodeFactory), rewritten);
}
private static DebugSourceDocument GetSourceDocument(DebugDocumentProvider debugDocumentProvider, SyntaxNode syntax)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
return GetSourceDocument(debugDocumentProvider, syntax, syntax.GetLocation().GetMappedLineSpan());
}
private static DebugSourceDocument GetSourceDocument(DebugDocumentProvider debugDocumentProvider, SyntaxNode syntax, FileLinePositionSpan span)
{
string text = ((FileLinePositionSpan)(ref span)).Path;
if (text.Length == 0)
{
text = syntax.SyntaxTree.FilePath;
}
return debugDocumentProvider.Invoke(text, "");
}
private BoundStatement AddAnalysisPoint(SyntaxNode syntaxForSpan, TextSpan alternateSpan, SyntheticBoundNodeFactory statementFactory)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
return AddAnalysisPoint(syntaxForSpan, syntaxForSpan.SyntaxTree.GetMappedLineSpan(alternateSpan, default(CancellationToken)), statementFactory);
}
private BoundStatement AddAnalysisPoint(SyntaxNode syntaxForSpan, SyntheticBoundNodeFactory statementFactory)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
return AddAnalysisPoint(syntaxForSpan, syntaxForSpan.GetLocation().GetMappedLineSpan(), statementFactory);
}
private BoundStatement AddAnalysisPoint(SyntaxNode syntaxForSpan, FileLinePositionSpan span, SyntheticBoundNodeFactory statementFactory)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//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_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: 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_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
int count = _spansBuilder.Count;
ArrayBuilder<SourceSpan> spansBuilder = _spansBuilder;
DebugSourceDocument sourceDocument = GetSourceDocument(_debugDocumentProvider, syntaxForSpan, span);
LinePosition val = ((FileLinePositionSpan)(ref span)).StartLinePosition;
int line = ((LinePosition)(ref val)).Line;
val = ((FileLinePositionSpan)(ref span)).StartLinePosition;
int character = ((LinePosition)(ref val)).Character;
val = ((FileLinePositionSpan)(ref span)).EndLinePosition;
int line2 = ((LinePosition)(ref val)).Line;
val = ((FileLinePositionSpan)(ref span)).EndLinePosition;
spansBuilder.Add(new SourceSpan(sourceDocument, line, character, line2, ((LinePosition)(ref val)).Character));
BoundArrayAccess left = statementFactory.ArrayAccess(statementFactory.Local(_methodPayload), statementFactory.Literal(count));
return statementFactory.Assignment(left, statementFactory.Literal(value: true));
}
private static SyntaxNode SyntaxForSpan(BoundStatement statement)
{
switch (statement.Kind)
{
case BoundKind.IfStatement:
return ((BoundIfStatement)statement).Condition.Syntax;
case BoundKind.WhileStatement:
return ((BoundWhileStatement)statement).Condition.Syntax;
case BoundKind.ForEachStatement:
return ((BoundForEachStatement)statement).Expression.Syntax;
case BoundKind.DoStatement:
return ((BoundDoStatement)statement).Condition.Syntax;
case BoundKind.UsingStatement:
{
BoundUsingStatement boundUsingStatement = (BoundUsingStatement)statement;
return ((BoundNode)(((object)boundUsingStatement.ExpressionOpt) ?? ((object)boundUsingStatement.DeclarationsOpt))).Syntax;
}
case BoundKind.FixedStatement:
return ((BoundFixedStatement)statement).Declarations.Syntax;
case BoundKind.LockStatement:
return ((BoundLockStatement)statement).Argument.Syntax;
case BoundKind.SwitchStatement:
return ((BoundSwitchStatement)statement).Expression.Syntax;
default:
return statement.Syntax;
}
}
private static MethodSymbol GetCreatePayloadOverload(CSharpCompilation compilation, WellKnownMember overload, SyntaxNode syntax, BindingDiagnosticBag diagnostics)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return (MethodSymbol)Binder.GetWellKnownTypeMember(compilation, overload, diagnostics, null, syntax);
}
private static SyntaxNode MethodDeclarationIfAvailable(SyntaxNode body)
{
SyntaxNode parent = body.Parent;
if (parent != null)
{
switch (parent.Kind())
{
case SyntaxKind.MethodDeclaration:
case SyntaxKind.OperatorDeclaration:
case SyntaxKind.ConstructorDeclaration:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.GetAccessorDeclaration:
case SyntaxKind.SetAccessorDeclaration:
case SyntaxKind.InitAccessorDeclaration:
return parent;
}
}
return body;
}
private static TextSpan SkipAttributes(SyntaxNode syntax)
{
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
switch (syntax.Kind())
{
case SyntaxKind.MethodDeclaration:
{
MethodDeclarationSyntax methodDeclarationSyntax = (MethodDeclarationSyntax)(object)syntax;
return SkipAttributes(syntax, methodDeclarationSyntax.AttributeLists, methodDeclarationSyntax.Modifiers, default(SyntaxToken), methodDeclarationSyntax.ReturnType);
}
case SyntaxKind.PropertyDeclaration:
{
PropertyDeclarationSyntax propertyDeclarationSyntax = (PropertyDeclarationSyntax)(object)syntax;
return SkipAttributes(syntax, propertyDeclarationSyntax.AttributeLists, propertyDeclarationSyntax.Modifiers, default(SyntaxToken), propertyDeclarationSyntax.Type);
}
case SyntaxKind.GetAccessorDeclaration:
case SyntaxKind.SetAccessorDeclaration:
case SyntaxKind.InitAccessorDeclaration:
{
AccessorDeclarationSyntax accessorDeclarationSyntax = (AccessorDeclarationSyntax)(object)syntax;
return SkipAttributes(syntax, accessorDeclarationSyntax.AttributeLists, accessorDeclarationSyntax.Modifiers, accessorDeclarationSyntax.Keyword, null);
}
case SyntaxKind.ConstructorDeclaration:
{
ConstructorDeclarationSyntax constructorDeclarationSyntax = (ConstructorDeclarationSyntax)(object)syntax;
return SkipAttributes(syntax, constructorDeclarationSyntax.AttributeLists, constructorDeclarationSyntax.Modifiers, constructorDeclarationSyntax.Identifier, null);
}
case SyntaxKind.OperatorDeclaration:
{
OperatorDeclarationSyntax operatorDeclarationSyntax = (OperatorDeclarationSyntax)(object)syntax;
return SkipAttributes(syntax, operatorDeclarationSyntax.AttributeLists, operatorDeclarationSyntax.Modifiers, operatorDeclarationSyntax.OperatorKeyword, null);
}
default:
return syntax.Span;
}
}
private static TextSpan SkipAttributes(SyntaxNode syntax, SyntaxList<AttributeListSyntax> attributes, SyntaxTokenList modifiers, SyntaxToken keyword, TypeSyntax? type)
{
//IL_0001: 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_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
TextSpan span = syntax.Span;
if (attributes.Count > 0)
{
TextSpan val = ((((SyntaxTokenList)(ref modifiers)).Node != null) ? ((SyntaxTokenList)(ref modifiers)).Span : ((((SyntaxToken)(ref keyword)).Node != null) ? ((SyntaxToken)(ref keyword)).Span : ((SyntaxNode)type).Span));
return new TextSpan(((TextSpan)(ref val)).Start, ((TextSpan)(ref span)).Length - (((TextSpan)(ref val)).Start - ((TextSpan)(ref span)).Start));
}
return span;
}
}