Exemple #1
0
        private IEnumerable <string> GetFolders(string fullPath, IProjectTreeServiceState state)
        {
            // Roslyn wants the effective set of folders from the source up to, but not including the project
            // root to handle the cases where linked files have a different path in the tree than what its path
            // on disk is. It uses these folders for things that create files alongside others, such as extract
            // interface.

            IProjectTree tree = state.TreeProvider.FindByPath(state.Tree, fullPath);

            if (tree == null)
            {
                yield break;    // We got a tree that is out-of-date than what our evaluation is based on
            }
            IProjectTree parent = tree;

            do
            {
                // Source files can be nested under other files
                if (parent.IsFolder)
                {
                    yield return(parent.Caption);
                }

                parent = parent.Parent;
            } while (!parent.IsRoot());
        }
Exemple #2
0
        private async Task <IProjectItemTree?> FindCompileItemByMonikerAsync(string documentMoniker)
        {
            IProjectTreeServiceState result = await _projectTree.Value.TreeService.PublishAnyNonLoadingTreeAsync();

            if (result.TreeProvider.FindByPath(result.Tree, documentMoniker) is IProjectItemTree treeItem &&
                treeItem.Parent?.Flags.Contains(ProjectTreeFlags.SourceFile) == false &&
                StringComparers.ItemTypes.Equals(treeItem.Item?.ItemType, Compile.SchemaName))
            {
                return(treeItem);
            }

            return(null);
        }
        private void AddSourceFile(string fullPath, IProjectTreeServiceState state = null)
        {
            if (!_sourceFiles.Contains(fullPath))
            {
                string[] folderNames = Array.Empty <string>();
                if (state != null)  // We're looking at a generated file, which doesn't appear in a tree.
                {
                    folderNames = GetFolders(fullPath, state).ToArray();
                }

                _sourceFiles.Add(fullPath);
                _context.AddSourceFile(fullPath, folderNames: folderNames); // TODO: IsInCurrentContext
            }
        }
        public virtual async Task <string?> GetFileAsync(SpecialFiles fileId, SpecialFileFlags flags, CancellationToken cancellationToken = default)
        {
            // Make sure at least have a tree before we start searching it
            IProjectTreeServiceState state = await _treeService.PublishAnyNonLoadingTreeAsync(cancellationToken);

            // Attempt to find an existing file/folder first
            string?path = await FindFileAsync(state.TreeProvider, state.Tree, flags);

            if (path == null)
            {
                // Otherwise, fall back and create it
                path = await CreateDefaultFileAsync(state.TreeProvider, state.Tree, flags);
            }

            return(path);
        }
        public async Task HandleAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> e, IProjectChangeDescription projectChange)
        {
            Requires.NotNull(e, nameof(e));
            Requires.NotNull(projectChange, nameof(projectChange));

            IProjectChangeDiff diff = projectChange.Difference;

            foreach (string filePath in diff.RemovedItems)
            {
                // Item includes are always relative to csproj/vbproj
                string fullPath = _project.MakeRooted(filePath);

                RemoveSourceFile(fullPath);
            }

            if (diff.AddedItems.Count > 0 || diff.RenamedItems.Count > 0 || diff.ChangedItems.Count > 0)
            {
                // Make sure the tree matches the same version of the evaluation that we're handling
                IProjectTreeServiceState treeState = await _projectTree.TreeService.PublishTreeAsync(e.ToRequirements(), blockDuringLoadingTree : true)
                                                     .ConfigureAwait(true);                               // TODO: https://github.com/dotnet/roslyn-project-system/issues/353

                foreach (string filePath in diff.AddedItems)
                {
                    string fullPath = _project.MakeRooted(filePath);

                    AddSourceFile(fullPath, treeState);
                }

                foreach (KeyValuePair <string, string> filePaths in diff.RenamedItems)
                {
                    string beforeFullPath = _project.MakeRooted(filePaths.Key);
                    string afterFullPath  = _project.MakeRooted(filePaths.Value);

                    RemoveSourceFile(beforeFullPath);
                    AddSourceFile(afterFullPath, treeState);
                }

                foreach (string filePath in diff.ChangedItems)
                {   // We add and then remove ChangedItems to handle Linked metadata changes
                    string fullPath = _project.MakeRooted(filePath);

                    RemoveSourceFile(fullPath);
                    AddSourceFile(fullPath);
                }
            }
        }
Exemple #6
0
        public override async Task HandleAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> e, IProjectChangeDescription projectChange, IWorkspaceProjectContext context, bool isActiveContext)
        {
            Requires.NotNull(e, nameof(e));
            Requires.NotNull(projectChange, nameof(projectChange));

            IProjectChangeDiff diff = projectChange.Difference;

            foreach (string filePath in diff.RemovedItems)
            {
                RemoveSourceFile(filePath, context);
            }

            if (diff.AddedItems.Count > 0 || diff.RenamedItems.Count > 0 || diff.ChangedItems.Count > 0)
            {
                // Make sure the tree matches the same version of the evaluation that we're handling for active project context.
                // If we are dealing with non- active project context, then just use the latest published tree.
                IProjectTreeServiceState treeState = isActiveContext ?
                                                     await PublishTreeAsync(e).ConfigureAwait(true) : // TODO: https://github.com/dotnet/roslyn-project-system/issues/353
                                                     await _projectTree.TreeService.PublishLatestTreeAsync(blockDuringLoadingTree : true).ConfigureAwait(true);

                foreach (string filePath in diff.AddedItems)
                {
                    AddSourceFile(filePath, context, isActiveContext, treeState);
                }

                foreach (KeyValuePair <string, string> filePaths in diff.RenamedItems)
                {
                    RemoveSourceFile(filePaths.Key, context);
                    AddSourceFile(filePaths.Value, context, isActiveContext, treeState);
                }

                foreach (string filePath in diff.ChangedItems)
                {
                    // We add and then remove ChangedItems to handle Linked metadata changes
                    RemoveSourceFile(filePath, context);
                    AddSourceFile(filePath, context, isActiveContext);
                }
            }
        }
Exemple #7
0
        private void AddSourceFile(string fullPath, IWorkspaceProjectContext context, bool isActiveContext, IProjectTreeServiceState state = null)
        {
            fullPath = _project.MakeRooted(fullPath);

            if (!_sourceFilesByContext.TryGetValue(context, out HashSet <string> sourceFiles))
            {
                sourceFiles = new HashSet <string>(StringComparers.Paths);
                _sourceFilesByContext.Add(context, sourceFiles);
            }
            else if (sourceFiles.Contains(fullPath))
            {
                return;
            }

            string[] folderNames = Array.Empty <string>();
            if (state != null)  // We're looking at a generated file, which doesn't appear in a tree.
            {
                folderNames = GetFolders(fullPath, state).ToArray();
            }

            sourceFiles.Add(fullPath);
            context.AddSourceFile(fullPath, folderNames: folderNames, isInCurrentContext: isActiveContext);
        }