/// <summary> /// Searches in current solution and in the global cache for the given file and returns it. /// If not found, file will be parsed. /// </summary> /// <param name="file"></param> /// <returns></returns> public static IAbstractSyntaxTree GetFileSyntaxTree(string file, out DProject OwnerProject) { OwnerProject = null; if (CoreManager.CurrentSolution != null) { foreach (var prj in CoreManager.CurrentSolution) { var dprj = prj as DProject; if (dprj != null && dprj.ContainsFile(file)) { OwnerProject = dprj; return(dprj.ParsedModules.GetModuleByFileName(file, dprj.BaseDirectory)); } } } var pcl = ParseCacheList.Create(DSettings.Instance.dmd1.ASTCache, DSettings.Instance.dmd2.ASTCache); IAbstractSyntaxTree ret = null; foreach (var pc in pcl) { foreach (var pdir in pc.ParsedDirectories) { if (file.StartsWith(pdir) && (ret = pc.GetModuleByFileName(file, pdir)) != null) { return(ret); } } } return(DParser.ParseFile(file)); }
public static EditorData GetEditorData(MonoDevelop.Ide.Gui.Document doc = null) { var ed = new EditorData(); if (doc == null) { doc = IdeApp.Workbench.ActiveDocument; } if (doc == null || doc.FileName == FilePath.Null || IdeApp.ProjectOperations.CurrentSelectedSolution == null) { return(null); } var editor = doc.GetContent <ITextBuffer>(); if (editor == null) { return(null); } int line, column; editor.GetLineColumnFromPosition(editor.CursorPosition, out line, out column); ed.CaretLocation = new CodeLocation(column, line); ed.CaretOffset = editor.CursorPosition; var ast = doc.ParsedDocument as ParsedDModule; var Project = doc.Project as DProject; ed.SyntaxTree = ast.DDom as DModule; ed.ModuleCode = editor.Text; if (ed.SyntaxTree == null) { return(null); } // Encapsule editor data for resolving ed.ParseCache = Project != null ? Project.ParseCache : ParseCacheList.Create(DCompilerService.Instance.GetDefaultCompiler().ParseCache); return(ed); }
public static ParseCacheList EnumAvailableModules(DProject Project = null) { if (Project != null) { var pcl = ParseCacheList.Create(Project.LocalFileCache, Project.LocalIncludeCache, Project.Compiler.ParseCache); // Automatically include dep projects' caches foreach (var dep in Project.DependingProjects) { pcl.Add(dep.LocalFileCache); } return(pcl); } else { return(ParseCacheList.Create(DCompilerService.Instance.GetDefaultCompiler().ParseCache)); } }
public override List <Change> PerformChanges(RefactoringOptions options, object prop) { #region Init var renameProperties = prop as RenameProperties; if (renameProperties == null) { return(null); } var changes = new List <Change>(); var doc = options.Document; if (doc == null) { return(null); } var ddoc = doc.ParsedDocument as ParsedDModule; if (ddoc == null) { return(null); } var n = options.SelectedItem as INode; if (n == null) { return(null); } var project = doc.HasProject ? doc.Project as DProject : null; var parseCache = project != null ? project.ParseCache : ParseCacheList.Create(DCompilerService.Instance.GetDefaultCompiler().ParseCache); var modules = project == null ? (IEnumerable <IAbstractSyntaxTree>) new[] { (Ide.IdeApp.Workbench.ActiveDocument.ParsedDocument as ParsedDModule).DDom } : project.LocalFileCache; var ctxt = ResolutionContext.Create(parseCache, null, null); #endregion // Enumerate references foreach (var mod in modules) { if (mod == null) { continue; } var references = D_Parser.Refactoring.ReferencesFinder.Scan(mod, n, ctxt).ToList(); if (((IAbstractSyntaxTree)n.NodeRoot).FileName == mod.FileName) { references.Insert(0, new IdentifierDeclaration(n.Name) { Location = n.NameLocation }); } if (references.Count < 1) { continue; } var txt = TextFileProvider.Instance.GetEditableTextFile(new FilePath(mod.FileName)); foreach (ISyntaxRegion reference in references) { changes.Add(new TextReplaceChange { FileName = mod.FileName, InsertedText = renameProperties.NewName, RemovedChars = n.Name.Length, Description = string.Format(GettextCatalog.GetString("Replace '{0}' with '{1}'"), n.Name, renameProperties.NewName), Offset = txt.GetPositionFromLineColumn(reference.Location.Line, reference.Location.Column) }); } } return(changes); }
bool UpdateMarkers() { try { var dom = SyntaxTree; if (dom == null) { return(false); } ResolverContextStack ctxt; var rr = DResolverWrapper.ResolveHoveredCode(out ctxt, Document); if (rr == null || rr.Length < 1) { return(false); } var parseCache = Document.HasProject ? (Document.Project as DProject).ParseCache : ParseCacheList.Create(DCompilerService.Instance.GetDefaultCompiler().ParseCache); var mr = rr[0] as DSymbol; if (mr == null) { return(false); } var referencedNode = mr.Definition; // Slightly hacky: To keep highlighting the id of e.g. a NewExpression, take the ctor's parent node (i.e. the class node) if (referencedNode is DMethod && ((DMethod)referencedNode).SpecialType == DMethod.MethodType.Constructor) { mr = mr.Base as DSymbol; referencedNode = mr.Definition; } try { var references = D_Parser.Refactoring.ReferencesFinder.Scan(dom, referencedNode, ctxt).ToList(); // Highlight the node's definition location - only if the node is located in the current document if (referencedNode.NodeRoot is IAbstractSyntaxTree && (referencedNode.NodeRoot as IAbstractSyntaxTree).FileName == dom.FileName) { references.Add(new IdentifierDeclaration(referencedNode.Name) { Location = referencedNode.NameLocation, EndLocation = new CodeLocation(referencedNode.NameLocation.Column + referencedNode.Name.Length, referencedNode.NameLocation.Line) }); } if (references.Count > 0) { ShowReferences(references); } } catch (Exception ex) { LoggingService.LogWarning("Error during usage highlighting analysis", ex); } } catch (Exception ex) { LoggingService.LogDebug("Error while highlighting symbol usages", ex); } return(false); }
static IEnumerable <SearchResult> FindReferences( DProject project, INode member, ISearchProgressMonitor monitor = null) { var searchResults = new List <SearchResult>(); var parseCache = project != null ? project.ParseCache : ParseCacheList.Create(DCompilerService.Instance.GetDefaultCompiler().ParseCache); var modules = project == null ? project.LocalFileCache as IEnumerable <IAbstractSyntaxTree> : new[] { (Ide.IdeApp.Workbench.ActiveDocument.ParsedDocument as MonoDevelop.D.Parser.ParsedDModule).DDom }; if (monitor != null) { monitor.BeginStepTask("Scan for references", modules.Count(), 1); } List <ISyntaxRegion> references = null; foreach (var mod in modules) { if (mod == null) { continue; } try { references = ReferencesFinder.Scan(mod, member, new ResolverContextStack(parseCache, new ResolverContext())).ToList(); if (member != null && member.NodeRoot != null && (member.NodeRoot as IAbstractSyntaxTree).FileName == mod.FileName) { references.Insert(0, new IdentifierDeclaration(member.Name) { Location = member.NameLocation, EndLocation = new CodeLocation(member.NameLocation.Column + member.Name.Length, member.NameLocation.Line) }); } if (references.Count < 1) { if (monitor != null) { monitor.Step(1); } continue; } // Sort the references by code location references.Sort(new IdLocationComparer()); // Get actual document code var targetDoc = Ide.TextFileProvider.Instance.GetTextEditorData(new FilePath(mod.FileName)); foreach (var reference in references) { CodeLocation loc; if (reference is AbstractTypeDeclaration) { loc = ((AbstractTypeDeclaration)reference).NonInnerTypeDependendLocation; } else if (reference is IExpression) { loc = ((IExpression)reference).Location; } else { continue; } searchResults.Add(new SearchResult(new FileProvider(mod.FileName, project), targetDoc.LocationToOffset(loc.Line, loc.Column), member.Name.Length)); } } catch (Exception ex) { LoggingService.LogWarning("Error during reference search", ex); } if (monitor != null) { monitor.Step(1); } } if (monitor != null) { monitor.EndTask(); } return(searchResults); }
public bool Run(DProject project, INode targetMember, string newName = null) { if (!CanRename(targetMember) || Ide.IdeApp.Workbench.ActiveDocument == null) { return(false); } n = targetMember; // Request new name if (newName == null) { newName = MessageService.GetTextResponse("Enter a new name", "Symbol rename", n.Name); } if (newName == null || newName == n.Name) { return(false); } // Validate new name if (string.IsNullOrWhiteSpace(newName)) { MessageService.ShowError("Symbol name must not be empty!"); return(false); } foreach (var c in newName) { if (!D_Parser.Completion.CtrlSpaceCompletionProvider.IsIdentifierChar(c)) { MessageService.ShowError("Character '" + c + "' in " + newName + " not allowed as identifier character!"); return(false); } } // Setup locals var parseCache = project != null ? project.ParseCache : ParseCacheList.Create(DCompilerService.Instance.GetDefaultCompiler().ParseCache); var modules = project == null ? (IEnumerable <IAbstractSyntaxTree>) new[] { (Ide.IdeApp.Workbench.ActiveDocument.ParsedDocument as MonoDevelop.D.Parser.ParsedDModule).DDom } : project.LocalFileCache; foundReferences = new Dictionary <string, List <CodeLocation> >(); var ctxt = new ResolverContextStack(parseCache, new ResolverContext()); // Enumerate references foreach (var mod in modules) { if (mod == null) { continue; } var references = D_Parser.Refactoring.ReferencesFinder.Scan(mod, n, ctxt).ToList(); if ((n.NodeRoot as IAbstractSyntaxTree).FileName == mod.FileName) { references.Insert(0, new IdentifierDeclaration(n.Name) { Location = n.NameLocation }); } if (references.Count < 1) { continue; } references.Sort(new ReferenceFinding.IdLocationComparer(true)); if (!foundReferences.ContainsKey(mod.FileName)) { foundReferences.Add(mod.FileName, new List <CodeLocation>()); } var moduleRefList = foundReferences[mod.FileName]; foreach (var reference in references) { moduleRefList.Add(reference.Location); } } if (foundReferences.Count < 1) { return(false); } // Replace occurences foreach (var kv1 in foundReferences) { var doc = TextFileProvider.Instance.GetEditableTextFile(new FilePath(kv1.Key)); if (doc != null) { foreach (var kv2 in kv1.Value) { int offset = doc.GetPositionFromLineColumn(kv2.Line, kv2.Column); doc.DeleteText(offset, n.Name.Length); doc.InsertText(offset, newName); } // If project file not open for editing, reparse it if (project != null && !IdeApp.Workbench.Documents.Any((Ide.Gui.Document d) => { if (d.IsFile && d.FileName == kv1.Key) { return(true); } return(false); })) { project.ReparseModule(kv1.Key); } } } // Assign new name to the node n.Name = newName; /* * // Prepare current editor (setup textlinks and anchors) * var doc = Ide.IdeApp.Workbench.ActiveDocument; * * if (doc == null || !doc.IsFile || !foundReferences.ContainsKey(doc.FileName)) * return false; * * var editor = doc.Editor; * var localReferences = foundReferences[doc.FileName]; * * List<TextLink> links = new List<TextLink>(); * TextLink link = new TextLink("name"); * int baseOffset = Int32.MaxValue; * * * foreach (var r in localReferences) * { * baseOffset = Math.Min(baseOffset, editor.Document.LocationToOffset(r.Line, r.Column)); * } * foreach (var r in localReferences) * { * var segment = new Segment(editor.Document.LocationToOffset(r.Line, r.Column) - baseOffset, n.Name.Length); * if (segment.Offset <= editor.Caret.Offset - baseOffset && editor.Caret.Offset - baseOffset <= segment.EndOffset) * { * link.Links.Insert(0, segment); * } * else * { * link.AddLink(segment); * } * } * * links.Add(link); * if (editor.CurrentMode is TextLinkEditMode) * ((TextLinkEditMode)editor.CurrentMode).ExitTextLinkMode(); * var tle = new TextLinkEditMode(editor.Parent, baseOffset, links); * tle.SetCaretPosition = false; * tle.SelectPrimaryLink = true; * * // Show rename helper popup * if (tle.ShouldStartTextLinkMode) * { * var helpWindow = new ModeHelpWindow(); * helpWindow.TransientFor = IdeApp.Workbench.RootWindow; * helpWindow.TitleText = "<b>Renaming " + (n as AbstractNode).ToString(false) + "</b>"; * helpWindow.Items.Add(new KeyValuePair<string, string>(GettextCatalog.GetString("<b>Key</b>"), GettextCatalog.GetString("<b>Behavior</b>"))); * helpWindow.Items.Add(new KeyValuePair<string, string>(GettextCatalog.GetString("<b>Return</b>"), GettextCatalog.GetString("<b>Accept</b> this refactoring."))); * helpWindow.Items.Add(new KeyValuePair<string, string>(GettextCatalog.GetString("<b>Esc</b>"), GettextCatalog.GetString("<b>Cancel</b> this refactoring."))); * tle.HelpWindow = helpWindow; * tle.Cancel += delegate * { * if (tle.HasChangedText) * editor.Document.Undo(); * }; * helpWindow.Destroyed += (object o, EventArgs e) => * { * if (tle.HasChangedText) * { * * } * }; * tle.OldMode = editor.CurrentMode; * tle.StartMode(); * editor.CurrentMode = tle; * } * else * return false; */ return(true); }
public void BuildUfcsCache() { ParsedModules.UfcsCache.Update(ParseCacheList.Create(ParsedModules, CompilerConfiguration.ASTCache), null, ParsedModules); }