예제 #1
0
        /// <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));
        }
예제 #2
0
        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);
        }
예제 #3
0
        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));
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
 public void BuildUfcsCache()
 {
     ParsedModules.UfcsCache.Update(ParseCacheList.Create(ParsedModules, CompilerConfiguration.ASTCache), null, ParsedModules);
 }