private IEntity FindEntityInRelevantAssemblies(string navigateTo, IEnumerable <LoadedAssembly> relevantAssemblies) { ITypeReference typeRef = null; IMemberReference memberRef = null; if (navigateTo.StartsWith("T:", StringComparison.Ordinal)) { typeRef = IdStringProvider.ParseTypeName(navigateTo); } else { memberRef = IdStringProvider.ParseMemberIdString(navigateTo); typeRef = memberRef.DeclaringTypeReference; } foreach (LoadedAssembly asm in relevantAssemblies.ToList()) { var module = asm.GetPEFileOrNull(); if (CanResolveTypeInPEFile(module, typeRef, out var typeHandle)) { ICompilation compilation = typeHandle.Kind == HandleKind.ExportedType ? new DecompilerTypeSystem(module, module.GetAssemblyResolver()) : new SimpleCompilation(module, MinimalCorlib.Instance); return(memberRef == null ? typeRef.Resolve(new SimpleTypeResolveContext(compilation)) as ITypeDefinition : (IEntity)memberRef.Resolve(new SimpleTypeResolveContext(compilation))); } } return(null); }
public IEnumerable <ILLocalVariable> GetLocalVariables(IMethod method) { string id = IdStringProvider.GetIdString(method.MemberDefinition); var file = GetSymbols(method); if (file == null || !file.DebugSymbols.ContainsKey(id)) { return(Enumerable.Empty <ILLocalVariable>()); } var symbols = file.DebugSymbols[id]; var context = new SimpleTypeResolveContext(method); var loader = new CecilLoader(); return(symbols.LocalVariables.Where(v => v.OriginalVariable != null).Select( v => new Debugger.ILLocalVariable() { Index = v.OriginalVariable.Index, Type = loader.ReadTypeReference(v.Type).Resolve(context), Name = v.Name, IsCompilerGenerated = false, ILRanges = new [] { new ILRange(0, int.MaxValue) } })); }
public Debugger.SequencePoint GetSequencePoint(IMethod method, int iloffset) { string id = IdStringProvider.GetIdString(method.MemberDefinition); var file = GetSymbols(method); if (file == null || !file.DebugSymbols.ContainsKey(id)) { return(null); } var symbols = file.DebugSymbols[id]; var seqs = symbols.SequencePoints; var seq = seqs.FirstOrDefault(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To)); if (seq == null) { seq = seqs.FirstOrDefault(p => iloffset <= p.ILOffset); } if (seq != null) { // Use the widest sequence point containing the IL offset iloffset = seq.ILOffset; seq = seqs.Where(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To)) .OrderByDescending(p => p.ILRanges.Last().To - p.ILRanges.First().From) .FirstOrDefault(); return(seq.ToDebugger(symbols, file.FileName)); } return(null); }
public bool NavigateToEntity(IEntity entity) { if (entity == null) { throw new ArgumentNullException("entity"); } // Get the underlying entity for generic instance members if (entity is IMember) { entity = ((IMember)entity).MemberDefinition; } ITypeDefinition declaringType = (entity as ITypeDefinition) ?? entity.DeclaringTypeDefinition; if (declaringType == null) { return(false); } // get the top-level type while (declaringType.DeclaringTypeDefinition != null) { declaringType = declaringType.DeclaringTypeDefinition; } FileName assemblyLocation = declaringType.ParentAssembly.GetRuntimeAssemblyLocation(); if (assemblyLocation != null && File.Exists(assemblyLocation)) { NavigateTo(assemblyLocation, declaringType.ReflectionName, IdStringProvider.GetIdString(entity)); return(true); } return(false); }
static void Check(IEntity entity, ITypeResolveContext context, HashSet <string> idStrings) { string id = IdStringProvider.GetIdString(entity); if (!idStrings.Add(id)) { throw new InvalidOperationException("Duplicate ID string " + id); } IEntity resolvedEntity = IdStringProvider.FindEntity(id, context); if (resolvedEntity != entity) { throw new InvalidOperationException(id); } }
bool TryGetDocumentation(IEntity entity, out XElement documentation) { if (entity is null) { documentation = null; return(false); } if (!documentationProviders.TryGetValue(entity.ParentModule, out IDocumentationProvider documentationProvider)) { documentationProvider = XmlDocLoader.LoadDocumentation(entity.ParentModule.PEFile); documentationProviders.Add(entity.ParentModule, documentationProvider); } documentation = ConvertToDocumentation(documentationProvider?.GetDocumentation(entity)); if (documentation.HasInheritDoc(out XElement inheritDoc)) { string referenceName = inheritDoc.GetReferenceName(); if (referenceName is null) { XElement baseDocumentation = null; if (entity is ITypeDefinition type) { type.GetBaseTypeDefinitions().FirstOrDefault(t => TryGetDocumentation(t, out baseDocumentation)); } else { string id = entity.GetIdString().Substring(entity.DeclaringTypeDefinition.GetIdString().Length); entity .DeclaringTypeDefinition .GetBaseTypeDefinitions() .SelectMany(t => t.Members) .FirstOrDefault(e => e.GetIdString().Substring(e.DeclaringTypeDefinition.GetIdString().Length) == id && TryGetDocumentation(e, out baseDocumentation)); } documentation = baseDocumentation; } else { return(TryGetDocumentation(IdStringProvider.FindEntity(referenceName, _resolver), out documentation)); } } return(documentation != null); }
public IEnumerable <ILRange> GetIgnoredILRanges(IMethod method) { string id = IdStringProvider.GetIdString(method.MemberDefinition); var file = GetSymbols(method); if (file == null || !file.DebugSymbols.ContainsKey(id)) { return new ILRange[] { } } ; var symbols = file.DebugSymbols[id]; int codesize = symbols.CecilMethod.Body.CodeSize; var inv = ICSharpCode.Decompiler.ILAst.ILRange.Invert(symbols.SequencePoints.SelectMany(s => s.ILRanges), codesize); return(inv.Select(r => new ILRange(r.From, r.To))); }
void HandleCommandLineArgumentsAfterShowList(CommandLineArguments args) { if (nugetPackagesToLoad.Count > 0) { LoadAssemblies(nugetPackagesToLoad, commandLineLoadedAssemblies, focusNode: false); nugetPackagesToLoad.Clear(); } if (args.NavigateTo != null) { bool found = false; if (args.NavigateTo.StartsWith("N:", StringComparison.Ordinal)) { string namespaceName = args.NavigateTo.Substring(2); foreach (LoadedAssembly asm in commandLineLoadedAssemblies) { AssemblyTreeNode asmNode = assemblyListTreeNode.FindAssemblyNode(asm); if (asmNode != null) { NamespaceTreeNode nsNode = asmNode.FindNamespaceNode(namespaceName); if (nsNode != null) { found = true; SelectNode(nsNode); break; } } } } else { foreach (LoadedAssembly asm in commandLineLoadedAssemblies) { var def = asm.GetPEFileOrNull(); if (def != null) { var compilation = new SimpleCompilation(def, MinimalCorlib.Instance); var mr = IdStringProvider.FindEntity(args.NavigateTo, new SimpleTypeResolveContext(compilation)); if (mr != null) { found = true; // Defer JumpToReference call to allow an assembly that was loaded while // resolving a type-forwarder in FindMemberByKey to appear in the assembly list. Dispatcher.BeginInvoke(new Action(() => JumpToReference(mr)), DispatcherPriority.Loaded); break; } } } } if (!found) { AvalonEditTextOutput output = new AvalonEditTextOutput(); output.Write(string.Format("Cannot find '{0}' in command line specified assemblies.", args.NavigateTo)); decompilerTextView.ShowText(output); } } else if (commandLineLoadedAssemblies.Count == 1) { // NavigateTo == null and an assembly was given on the command-line: // Select the newly loaded assembly JumpToReference(commandLineLoadedAssemblies[0].GetPEFileOrNull()); } if (args.Search != null) { SearchPane.Instance.SearchTerm = args.Search; SearchPane.Instance.Show(); } commandLineLoadedAssemblies.Clear(); // clear references once we don't need them anymore }
#pragma warning disable 618 public static XmlNode GetMonodocDocumentation(this IEntity member) { if (member.SymbolKind == SymbolKind.TypeDefinition) { var helpXml = HelpService.HelpTree != null?HelpService.HelpTree.GetHelpXml(IdStringProvider.GetIdString(member)) : null; if (helpXml == null) { return(null); } return(helpXml.SelectSingleNode("/Type/Docs")); } var declaringXml = HelpService.HelpTree != null && member.DeclaringTypeDefinition != null?HelpService.HelpTree.GetHelpXml(member.DeclaringTypeDefinition.GetIdString()) : null; if (declaringXml == null) { return(null); } switch (member.SymbolKind) { case SymbolKind.Method: { var nodes = declaringXml.SelectNodes("/Type/Members/Member[@MemberName='" + member.Name + "']"); XmlNode node = nodes.Count == 1 ? nodes [0] : FindMatch((IMethod)member, nodes); if (node != null) { System.Xml.XmlNode result = node.SelectSingleNode("Docs"); return(result); } return(null); } case SymbolKind.Constructor: { var nodes = declaringXml.SelectNodes("/Type/Members/Member[@MemberName='.ctor']"); XmlNode node = nodes.Count == 1 ? nodes [0] : FindMatch((IMethod)member, nodes); if (node != null) { System.Xml.XmlNode result = node.SelectSingleNode("Docs"); return(result); } return(null); } default: return(declaringXml.SelectSingleNode("/Type/Members/Member[@MemberName='" + member.Name + "']/Docs")); } }
void HandleCommandLineArgumentsAfterShowList(CommandLineArguments args) { if (nugetPackagesToLoad.Count > 0) { LoadAssemblies(nugetPackagesToLoad, commandLineLoadedAssemblies, focusNode: false); nugetPackagesToLoad.Clear(); } if (args.NavigateTo != null) { bool found = false; if (args.NavigateTo.StartsWith("N:", StringComparison.Ordinal)) { string namespaceName = args.NavigateTo.Substring(2); foreach (LoadedAssembly asm in commandLineLoadedAssemblies) { AssemblyTreeNode asmNode = assemblyListTreeNode.FindAssemblyNode(asm); if (asmNode != null) { NamespaceTreeNode nsNode = asmNode.FindNamespaceNode(namespaceName); if (nsNode != null) { found = true; SelectNode(nsNode); break; } } } } else { ITypeReference typeRef = null; IMemberReference memberRef = null; if (args.NavigateTo.StartsWith("T:", StringComparison.Ordinal)) { typeRef = IdStringProvider.ParseTypeName(args.NavigateTo); } else { memberRef = IdStringProvider.ParseMemberIdString(args.NavigateTo); typeRef = memberRef.DeclaringTypeReference; } foreach (LoadedAssembly asm in commandLineLoadedAssemblies) { var module = asm.GetPEFileOrNull(); if (CanResolveTypeInPEFile(module, typeRef, out var typeHandle)) { IEntity mr = null; ICompilation compilation = typeHandle.Kind == HandleKind.ExportedType ? new DecompilerTypeSystem(module, module.GetAssemblyResolver()) : new SimpleCompilation(module, MinimalCorlib.Instance); mr = memberRef == null ? typeRef.Resolve(new SimpleTypeResolveContext(compilation)) as ITypeDefinition : (IEntity)memberRef.Resolve(new SimpleTypeResolveContext(compilation)); if (mr != null && mr.ParentModule.PEFile != null) { found = true; // Defer JumpToReference call to allow an assembly that was loaded while // resolving a type-forwarder in FindMemberByKey to appear in the assembly list. Dispatcher.BeginInvoke(new Action(() => JumpToReference(mr)), DispatcherPriority.Loaded); break; } } } } if (!found) { AvalonEditTextOutput output = new AvalonEditTextOutput(); output.Write(string.Format("Cannot find '{0}' in command line specified assemblies.", args.NavigateTo)); decompilerTextView.ShowText(output); } } else if (commandLineLoadedAssemblies.Count == 1) { // NavigateTo == null and an assembly was given on the command-line: // Select the newly loaded assembly JumpToReference(commandLineLoadedAssemblies[0].GetPEFileOrNull()); } if (args.Search != null) { SearchPane.Instance.SearchTerm = args.Search; SearchPane.Instance.Show(); } commandLineLoadedAssemblies.Clear(); // clear references once we don't need them anymore }
XElement GetDocumentation(string id) => TryGetDocumentation(IdStringProvider.FindEntity(id, _resolver), out XElement documentation) ? documentation : null;
public static void OpenInILSpy(IEntity entity) { if (entity == null) { throw new ArgumentNullException("entity"); } // Get the underlying entity for generic instance members if (entity is IMember) { entity = ((IMember)entity).MemberDefinition; } // Try to find the assembly which contains the resolved type var assemblyLocation = entity.ParentAssembly.GetRuntimeAssemblyLocation(); if (string.IsNullOrEmpty(assemblyLocation)) { MessageService.ShowWarning("ILSpy AddIn: Could not determine the assembly location for " + entity.ParentAssembly.AssemblyName + "."); return; } string ilspyPath = GetILSpyExeFullPathInteractive(); if (string.IsNullOrEmpty(ilspyPath)) { return; } string commandLine = "/singleInstance \"" + assemblyLocation + "\" \"/navigateTo:" + IdStringProvider.GetIdString(entity) + "\""; LoggingService.Debug(ilspyPath + " " + commandLine); Process.Start(ilspyPath, commandLine); }