|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Internal.TypeSystem;
namespace ILCompiler
{
/// <summary>
/// Represents a stack trace emission policy.
/// </summary>
public abstract class StackTraceEmissionPolicy
{
public abstract MethodStackTraceVisibilityFlags GetMethodVisibility(MethodDesc method);
}
public class NoStackTraceEmissionPolicy : StackTraceEmissionPolicy
{
public override MethodStackTraceVisibilityFlags GetMethodVisibility(MethodDesc method)
{
return default;
}
}
/// <summary>
/// Stack trace emission policy that ensures presence of stack trace metadata for all
/// <see cref="Internal.TypeSystem.Ecma.EcmaMethod"/>-based methods.
/// </summary>
public class EcmaMethodStackTraceEmissionPolicy : StackTraceEmissionPolicy
{
private readonly MethodStackTraceVisibilityFlags _flags;
public EcmaMethodStackTraceEmissionPolicy(bool includeLineNumbers)
{
_flags = includeLineNumbers ? MethodStackTraceVisibilityFlags.HasLineNumbers : 0;
}
public override MethodStackTraceVisibilityFlags GetMethodVisibility(MethodDesc method)
{
MethodStackTraceVisibilityFlags result = _flags;
if (method.HasCustomAttribute("System.Diagnostics", "StackTraceHiddenAttribute")
|| (method.OwningType is MetadataType mdType && mdType.HasCustomAttribute("System.Diagnostics", "StackTraceHiddenAttribute"))
|| (method is Internal.IL.Stubs.ILStubMethod) || method.IsAsyncThunk()) // see MethodDesc::IsDiagnosticsHidden() in src/coreclr/vm/method.inl
{
result |= MethodStackTraceVisibilityFlags.IsHidden;
}
return (method.GetTypicalMethodDefinition() is Internal.TypeSystem.Ecma.EcmaMethod || (method.IsAsync && method.IsAsyncCall()))
? result | MethodStackTraceVisibilityFlags.HasMetadata
: result;
}
}
[Flags]
public enum MethodStackTraceVisibilityFlags
{
HasMetadata = 0x1,
IsHidden = 0x2,
HasLineNumbers = 0x4,
}
}
|