public bool TryDecompile() { Debug2.Assert(output is null); output = new DecompilerOutputImpl(); if (!StateMachineHelpers.TryGetKickoffMethod(method, out var containingMethod)) { containingMethod = method; } var ctx = new DecompilationContext() { CancellationToken = cancellationToken, CalculateILSpans = true, AsyncMethodBodyDecompilation = false, }; var info = TryDecompileCode(containingMethod, method.MDToken.Raw, ctx, output); if (info.debugInfo is null && containingMethod != method) { output.Clear(); // The decompiler can't decompile the iterator / async method, try again, // but only decompile the MoveNext method info = TryDecompileCode(method, method.MDToken.Raw, ctx, output); } debugInfo = info.debugInfo; return(debugInfo is not null); }
DocumentTabReferenceResult?CreateMemberRefResult(IDocumentTabService documentTabService, object? @ref) { var resolvedRef = ResolveMemberDef(@ref); if (!IsSupportedReference(resolvedRef)) { return(null); } if (resolvedRef is MethodDef method && StateMachineHelpers.TryGetKickoffMethod(method, out var kickoffMethod)) { @ref = kickoffMethod; resolvedRef = kickoffMethod; } var newRef = GetReference(@ref); var node = documentTabService.DocumentTreeView.FindNode(newRef); if (node is null) { // If it's eg. a TypeDef, its assembly has been removed from the document list or it // was never inserted because adding an assembly had been temporarily disabled. // Add the assembly to the list again. Next time the user clicks on the link, // FindNode() above will succeed. var def = @ref as IMemberDef ?? (@ref as ParamDef)?.DeclaringMethod; if (def is not null) { DsDocument?document = null; var mod = def.Module; if (mod is not null && mod.Assembly is not null) { document = DsDotNetDocument.CreateAssembly(DsDocumentInfo.CreateDocument(mod.Location), mod, false); } else if (mod is not null) { document = DsDotNetDocument.CreateModule(DsDocumentInfo.CreateDocument(mod.Location), mod, false); } if (document is not null) { var existingDocument = documentTabService.DocumentTreeView.DocumentService.GetOrAdd(document); if (existingDocument != document) { documentTabService.DocumentTreeView.DocumentService.ForceAdd(document, true, null); } } } return(null); }
DocumentTabReferenceResult CreateMemberRefResult(IDocumentTabService documentTabService, object @ref) { var resolvedRef = ResolveMemberDef(@ref); if (!IsSupportedReference(resolvedRef)) { return(null); } if (resolvedRef is MethodDef method && StateMachineHelpers.TryGetKickoffMethod(method, out var kickoffMethod)) { @ref = kickoffMethod; resolvedRef = kickoffMethod; } var newRef = GetReference(@ref); var node = documentTabService.DocumentTreeView.FindNode(newRef); if (node == null) { // If it's eg. a TypeDef, its assembly has been removed from the document list or it // was never inserted because adding an assembly had been temporarily disabled. // Add the assembly to the list again. Next time the user clicks on the link, // FindNode() above will succeed. var def = @ref as IMemberDef ?? (@ref as ParamDef)?.DeclaringMethod; if (def != null) { DsDocument document = null; var mod = def.Module; if (mod != null && mod.Assembly != null) { document = DsDotNetDocument.CreateAssembly(DsDocumentInfo.CreateDocument(mod.Location), mod, false); } else if (mod != null) { document = DsDotNetDocument.CreateModule(DsDocumentInfo.CreateDocument(mod.Location), mod, false); } if (document != null) { var existingDocument = documentTabService.DocumentTreeView.DocumentService.GetOrAdd(document); if (existingDocument != document) { documentTabService.DocumentTreeView.DocumentService.ForceAdd(document, true, null); } } } return(null); } var content = decompileDocumentTabContentFactory.Create(new DocumentTreeNodeData[] { node }); if (@ref is MethodStatementReference statementRef && statementRef.Offset != null) { return(new DocumentTabReferenceResult(content, null, a => { if (a.Success && !a.HasMovedCaret) { GoToReference(content, resolvedRef, statementRef.Method, statementRef.Offset.Value, content.WasNewContent); a.HasMovedCaret = true; } })); } return(new DocumentTabReferenceResult(content, null, a => { if (a.Success && !a.HasMovedCaret) { GoToReference(content, resolvedRef, content.WasNewContent); a.HasMovedCaret = true; } })); }