in resharper/resharper-unity/src/Unity.Rider/Integration/Protocol/UnityProfilerEventsHost.cs [28:125]
public class UnityProfilerEventsHost(
ILogger logger,
ISolution solution,
UnityProfilerInfoCollector unityProfilerInfoCollector,
Lifetime componentLifetime)
{
public void AdviseOpenFileByMethodName(UnityProfilerModel unityProfilerModel,
FrontendBackendHost frontendBackendHost, Lifetime lifetime)
{
unityProfilerModel.OpenFileBySampleInfo.SetAsync((_, sampleStackInfo) =>
{
var result = new RdTask<Unit>();
if (string.IsNullOrEmpty(sampleStackInfo.SampleStack) || string.IsNullOrEmpty(sampleStackInfo.SampleName))
return result;
using (ReadLockCookie.Create())
{
unityProfilerInfoCollector.OnOpenFileBySampleInfo();
try
{
NavigateToCode(sampleStackInfo.SampleStack);
}
catch (Exception e)
{
logger.Error(e);
result.Set(Unit.Instance);
}
try
{
ShowConsoleWithCallstack(frontendBackendHost, sampleStackInfo.SampleStack, sampleStackInfo.SampleName, lifetime);
}
catch (Exception e)
{
logger.Error(e);
result.Set(Unit.Instance);
}
}
return result;
});
}
private void ShowConsoleWithCallstack(FrontendBackendHost frontendBackendHost, string sampleStack,
string sampleName, Lifetime lifetime)
{
frontendBackendHost.Do(model => model.AllowSetForegroundWindow
.Start(lifetime, Unit.Instance).Result
.AdviseOnce(componentLifetime, _ => model.ActivateRider()));
sampleStack = sampleStack.Replace("/", "\n");
solution.GetComponent<RiderStackTraceHost>().ShowConsole(new StackTraceConsole(sampleName, sampleStack));
}
private void NavigateToCode(string profilerCallstack)
{
var stackTraceOptions = solution.GetComponent<StackTraceOptions>();
var parser = new StackTraceParser(profilerCallstack, solution,
solution.GetComponent<StackTracePathResolverCache>(), stackTraceOptions.GetState());
try
{
var rootNode = parser.Parse(0, profilerCallstack.Length);
IOccurrence? occurrence = null;
//Attempting to get the most bottom node
//callstack example:
// PlayerLoop
// |- Update.ScriptRunBehaviourUpdate
// |-- BehaviourUpdate
// |--- Assembly-CSharp.dll!MyNamespace1::HeavyScript1.Update() [Invoke]
foreach (var nodeNode in rootNode.Nodes)
{
if (nodeNode is IdentifierNode identifierNode)
{
var identifierNodeResolveState = identifierNode.ResolveState;
using (CompilationContextCookie.GetExplicitUniversalContextIfNotSet())
{
occurrence = identifierNodeResolveState.MainCandidate?
.GetNavigationDeclarations().FirstOrDefault() ?? occurrence;
}
}
}
if (occurrence != null)
occurrence.Navigate(solution,
solution.GetComponent<IMainWindowPopupWindowContext>().Source, true);
else
{
logger.Verbose($"No occurrence found for '{profilerCallstack}'");
}
}
catch (Exception e)
{
logger.LogException(e);
}
}
}