public RuleSetFile(string filePath, IVsFileChangeEx fileChangeService, VisualStudioRuleSetManager ruleSetManager)
            {
                _filePath = filePath;
                _ruleSetManager = ruleSetManager;

                ImmutableArray<string> includes;

                try
                {
                    includes = RuleSet.GetEffectiveIncludesFromFile(filePath);
                }
                catch (Exception e)
                {
                    // We couldn't read the rule set for whatever reason. Capture the exception
                    // so we can surface the error later, and subscribe to file change notifications
                    // so that we'll automatically reload the file if the user can fix the issue.
                    _optionsRead = true;
                    _specificDiagnosticOptions = ImmutableDictionary<string, ReportDiagnostic>.Empty;
                    _exception = e;

                    includes = ImmutableArray.Create(filePath);
                }

                _trackers = new List<FileChangeTracker>(capacity: includes.Length);

                foreach (var include in includes)
                {
                    var tracker = new FileChangeTracker(fileChangeService, include);
                    tracker.UpdatedOnDisk += IncludeUpdated;
                    tracker.StartFileChangeListeningAsync();

                    _trackers.Add(tracker);
                }
            }
Example #2
0
            internal Snapshot(
                VisualStudioMetadataReferenceManager provider,
                MetadataReferenceProperties properties,
                string fullPath,
                FileChangeTracker fileChangeTrackerOpt
                ) : base(properties, fullPath)
            {
                Debug.Assert(Properties.Kind == MetadataImageKind.Assembly);
                _provider             = provider;
                _fileChangeTrackerOpt = fileChangeTrackerOpt;

                _timestamp = new Lazy <DateTime>(
                    () =>
                {
                    try
                    {
                        _fileChangeTrackerOpt?.EnsureSubscription();

                        return(FileUtilities.GetFileTimeStamp(this.FilePath));
                    }
                    catch (IOException e)
                    {
                        // Reading timestamp of a file might fail.
                        // Let's remember the failure and report it to the compiler when it asks for metadata.
                        // We could let the Lazy hold onto this (since it knows how to rethrow exceptions), but
                        // our support of GetStorages needs to gracefully handle the case where we have no timestamp.
                        // If Lazy had a "IsValueFaulted" we could be cleaner here.
                        _error = e;
                        return(DateTime.MinValue);
                    }
                },
                    LazyThreadSafetyMode.PublicationOnly
                    );
            }
            public RuleSetFile(string filePath, IVsFileChangeEx fileChangeService, VisualStudioRuleSetManager ruleSetManager)
            {
                _filePath       = filePath;
                _ruleSetManager = ruleSetManager;

                ImmutableArray <string> includes;

                try
                {
                    includes = RuleSet.GetEffectiveIncludesFromFile(filePath);
                }
                catch (Exception e)
                {
                    // We couldn't read the rule set for whatever reason. Capture the exception
                    // so we can surface the error later, and subscribe to file change notifications
                    // so that we'll automatically reload the file if the user can fix the issue.
                    _optionsRead = true;
                    _specificDiagnosticOptions = ImmutableDictionary <string, ReportDiagnostic> .Empty;
                    _exception = e;

                    includes = ImmutableArray.Create(filePath);
                }

                _trackers = new List <FileChangeTracker>(capacity: includes.Length);

                foreach (var include in includes)
                {
                    var tracker = new FileChangeTracker(fileChangeService, include);
                    tracker.UpdatedOnDisk += IncludeUpdated;
                    tracker.StartFileChangeListeningAsync();

                    _trackers.Add(tracker);
                }
            }
            /// <summary>
            /// Creates a <see cref="StandardTextDocument"/>.
            /// <para>Note: getFolderNames maps from a VSITEMID to the folders this document should be contained in.</para>
            /// </summary>
            public StandardTextDocument(
                DocumentProvider documentProvider,
                AbstractProject project,
                DocumentKey documentKey,
                Func <uint, IReadOnlyList <string> > getFolderNames,
                SourceCodeKind sourceCodeKind,
                IVsFileChangeEx fileChangeService,
                ITextBuffer openTextBuffer,
                DocumentId id,
                EventHandler updatedOnDiskHandler,
                EventHandler <bool> openedHandler,
                EventHandler <bool> closingHandler)
            {
                Contract.ThrowIfNull(documentProvider);

                this.Project = project;
                this.Id      = id ?? DocumentId.CreateNewId(project.Id, documentKey.Moniker);
                _itemMoniker = documentKey.Moniker;

                var itemid = this.GetItemId();

                this.Folders = itemid == (uint)VSConstants.VSITEMID.Nil
                    ? SpecializedCollections.EmptyReadOnlyList <string>()
                    : getFolderNames(itemid);

                _documentProvider = documentProvider;

                this.Key            = documentKey;
                this.SourceCodeKind = sourceCodeKind;
                _fileChangeTracker  = new FileChangeTracker(fileChangeService, this.FilePath);
                _fileChangeTracker.UpdatedOnDisk += OnUpdatedOnDisk;

                _openTextBuffer  = openTextBuffer;
                _snapshotTracker = new ReiteratedVersionSnapshotTracker(openTextBuffer);

                // The project system does not tell us the CodePage specified in the proj file, so
                // we use null to auto-detect.
                _doNotAccessDirectlyLoader = new FileTextLoader(documentKey.Moniker, defaultEncoding: null);

                // If we aren't already open in the editor, then we should create a file change notification
                if (openTextBuffer == null)
                {
                    _fileChangeTracker.StartFileChangeListeningAsync();
                }

                if (updatedOnDiskHandler != null)
                {
                    UpdatedOnDisk += updatedOnDiskHandler;
                }

                if (openedHandler != null)
                {
                    Opened += openedHandler;
                }

                if (closingHandler != null)
                {
                    Closing += closingHandler;
                }
            }
            /// <summary>
            /// Creates a <see cref="StandardTextDocument"/>.
            /// </summary>
            public StandardTextDocument(
                DocumentProvider documentProvider,
                AbstractProject project,
                DocumentKey documentKey,
                ImmutableArray <string> folderNames,
                SourceCodeKind sourceCodeKind,
                IVsFileChangeEx fileChangeService,
                ITextBuffer openTextBuffer,
                DocumentId id,
                EventHandler updatedOnDiskHandler,
                EventHandler <bool> openedHandler,
                EventHandler <bool> closingHandler)
                : base(documentProvider.ThreadingContext)
            {
                Contract.ThrowIfNull(documentProvider);

                this.Project = project;
                this.Id      = id ?? DocumentId.CreateNewId(project.Id, documentKey.Moniker);
                _itemMoniker = documentKey.Moniker;

                this.Folders = folderNames;

                _documentProvider = documentProvider;

                this.Key            = documentKey;
                this.SourceCodeKind = sourceCodeKind;
                _fileChangeTracker  = new FileChangeTracker(fileChangeService, this.FilePath);
                _fileChangeTracker.UpdatedOnDisk += OnUpdatedOnDisk;

                _openTextBuffer  = openTextBuffer;
                _snapshotTracker = new ReiteratedVersionSnapshotTracker(openTextBuffer);

                // The project system does not tell us the CodePage specified in the proj file, so
                // we use null to auto-detect.
                _doNotAccessDirectlyLoader = new FileChangeTrackingTextLoader(_fileChangeTracker, new FileTextLoader(documentKey.Moniker, defaultEncoding: null));

                // If we aren't already open in the editor, then we should create a file change notification
                if (openTextBuffer == null)
                {
                    _fileChangeTracker.StartFileChangeListeningAsync();
                }

                if (updatedOnDiskHandler != null)
                {
                    UpdatedOnDisk += updatedOnDiskHandler;
                }

                if (openedHandler != null)
                {
                    Opened += openedHandler;
                }

                if (closingHandler != null)
                {
                    Closing += closingHandler;
                }
            }
            public StandardTextDocument(
                DocumentProvider documentProvider,
                IVisualStudioHostProject project,
                DocumentKey documentKey,
                IReadOnlyList<string> folderNames,
                SourceCodeKind sourceCodeKind,
                ITextUndoHistoryRegistry textUndoHistoryRegistry,
                IVsFileChangeEx fileChangeService,
                ITextBuffer openTextBuffer,
                DocumentId id,
                EventHandler updatedOnDiskHandler,
                EventHandler<bool> openedHandler,
                EventHandler<bool> closingHandler)
            {
                Contract.ThrowIfNull(documentProvider);

                this.Project = project;
                this.Id = id ?? DocumentId.CreateNewId(project.Id, documentKey.Moniker);
                this.Folders = folderNames;

                _documentProvider = documentProvider;

                this.Key = documentKey;
                this.SourceCodeKind = sourceCodeKind;
                _itemMoniker = documentKey.Moniker;
                _textUndoHistoryRegistry = textUndoHistoryRegistry;
                _fileChangeTracker = new FileChangeTracker(fileChangeService, this.FilePath);
                _fileChangeTracker.UpdatedOnDisk += OnUpdatedOnDisk;

                _openTextBuffer = openTextBuffer;
                _snapshotTracker = new ReiteratedVersionSnapshotTracker(openTextBuffer);

                // The project system does not tell us the CodePage specified in the proj file, so
                // we use null to auto-detect.
                _doNotAccessDirectlyLoader = new FileTextLoader(documentKey.Moniker, defaultEncoding: null);

                // If we aren't already open in the editor, then we should create a file change notification
                if (openTextBuffer == null)
                {
                    _fileChangeTracker.StartFileChangeListeningAsync();
                }

                if (updatedOnDiskHandler != null)
                {
                    UpdatedOnDisk += updatedOnDiskHandler;
                }

                if (openedHandler != null)
                {
                    Opened += openedHandler;
                }

                if (closingHandler != null)
                {
                    Closing += closingHandler;
                }
            }
Example #7
0
 public VisualStudioAnalyzer(string fullPath, IVsFileChangeEx fileChangeService, HostDiagnosticUpdateSource hostDiagnosticUpdateSource, ProjectId projectId, Workspace workspace, IAnalyzerAssemblyLoader loader, string language)
 {
     _fullPath = fullPath;
     _tracker  = new FileChangeTracker(fileChangeService, fullPath);
     _tracker.UpdatedOnDisk += OnUpdatedOnDisk;
     _tracker.StartFileChangeListeningAsync();
     _hostDiagnosticUpdateSource = hostDiagnosticUpdateSource;
     _projectId = projectId;
     _workspace = workspace;
     _loader    = loader;
     _language  = language;
 }
 public VisualStudioAnalyzer(string fullPath, IVsFileChangeEx fileChangeService, HostDiagnosticUpdateSource hostDiagnosticUpdateSource, ProjectId projectId, Workspace workspace, string language)
 {
     _fullPath = fullPath;
     _tracker = new FileChangeTracker(fileChangeService, fullPath);
     _tracker.UpdatedOnDisk += OnUpdatedOnDisk;
     _tracker.StartFileChangeListeningAsync();
     _tracker.EnsureSubscription();
     _hostDiagnosticUpdateSource = hostDiagnosticUpdateSource;
     _projectId = projectId;
     _workspace = workspace;
     _language = language;
 }
Example #9
0
        public VisualStudioMetadataReference(
            VisualStudioMetadataReferenceManager provider,
            string filePath,
            MetadataReferenceProperties properties)
        {
            Contract.ThrowIfTrue(properties.Kind != MetadataImageKind.Assembly);

            _provider   = provider;
            _properties = properties;

            // We don't track changes to netmodules linked to the assembly.
            // Any legitimate change in a linked module will cause the assembly to change as well.
            _fileChangeTracker = new FileChangeTracker(provider.FileChangeService, filePath);
            _fileChangeTracker.UpdatedOnDisk += OnUpdatedOnDisk;
            _fileChangeTracker.StartFileChangeListeningAsync();
        }
Example #10
0
            public StandardTextDocument(
                DocumentProvider documentProvider,
                IVisualStudioHostProject project,
                DocumentKey documentKey,
                uint itemId,
                SourceCodeKind sourceCodeKind,
                ITextBufferFactoryService textBufferFactoryService,
                ITextUndoHistoryRegistry textUndoHistoryRegistry,
                IVsFileChangeEx fileChangeService,
                ITextBuffer openTextBuffer,
                DocumentId id)
            {
                Contract.ThrowIfNull(documentProvider);
                Contract.ThrowIfNull(textBufferFactoryService);

                this.Project = project;
                this.Id      = id ?? DocumentId.CreateNewId(project.Id, documentKey.Moniker);
                this.Folders = project.GetFolderNames(itemId);

                // TODO:
                // this one doesn't work for asynchronous project load situation where shared projects is loaded after one uses shared file.
                // we need to figure out what to do on those case. but this works for project k case.
                // opened an issue to track this issue - https://github.com/dotnet/roslyn/issues/1859
                this.SharedHierarchy = project.Hierarchy == null ? null : LinkedFileUtilities.GetSharedHierarchyForItem(project.Hierarchy, itemId);
                _documentProvider    = documentProvider;

                this.Key                          = documentKey;
                this.SourceCodeKind               = sourceCodeKind;
                _itemMoniker                      = documentKey.Moniker;
                _textBufferFactoryService         = textBufferFactoryService;
                _textUndoHistoryRegistry          = textUndoHistoryRegistry;
                _fileChangeTracker                = new FileChangeTracker(fileChangeService, this.FilePath);
                _fileChangeTracker.UpdatedOnDisk += OnUpdatedOnDisk;

                _openTextBuffer  = openTextBuffer;
                _snapshotTracker = new ReiteratedVersionSnapshotTracker(openTextBuffer);

                // The project system does not tell us the CodePage specified in the proj file, so
                // we use null to auto-detect.
                _doNotAccessDirectlyLoader = new FileTextLoader(documentKey.Moniker, defaultEncoding: null);

                // If we aren't already open in the editor, then we should create a file change notification
                if (openTextBuffer == null)
                {
                    _fileChangeTracker.StartFileChangeListeningAsync();
                }
            }
        public VisualStudioMetadataReference(
            VisualStudioMetadataReferenceManager provider,
            IVisualStudioHostProject hostProject,
            string filePath,
            MetadataReferenceProperties properties)
        {
            Contract.ThrowIfTrue(properties.Kind != MetadataImageKind.Assembly);

            _provider = provider;
            _hostProject = hostProject;
            _properties = properties;

            // We don't track changes to netmodules linked to the assembly.
            // Any legitimate change in a linked module will cause the assembly to change as well.
            _fileChangeTracker = new FileChangeTracker(provider.FileChangeService, filePath);
            _fileChangeTracker.UpdatedOnDisk += OnUpdatedOnDisk;
            _fileChangeTracker.StartFileChangeListeningAsync();
        }
Example #12
0
            public StandardTextDocument(
                DocumentProvider documentProvider,
                IVisualStudioHostProject project,
                DocumentKey documentKey,
                uint itemId,
                SourceCodeKind sourceCodeKind,
                ITextBufferFactoryService textBufferFactoryService,
                ITextUndoHistoryRegistry textUndoHistoryRegistry,
                IVsFileChangeEx fileChangeService,
                ITextBuffer openTextBuffer,
                DocumentId id)
            {
                Contract.ThrowIfNull(documentProvider);
                Contract.ThrowIfNull(textBufferFactoryService);

                this.Project = project;
                this.Id      = id ?? DocumentId.CreateNewId(project.Id, documentKey.Moniker);
                this.Folders = project.GetFolderNames(itemId);

                this.SharedHierarchy = project.Hierarchy == null ? null : LinkedFileUtilities.GetSharedHierarchyForItem(project.Hierarchy, itemId);
                _documentProvider    = documentProvider;

                this.Key                          = documentKey;
                this.SourceCodeKind               = sourceCodeKind;
                _itemMoniker                      = documentKey.Moniker;
                _textBufferFactoryService         = textBufferFactoryService;
                _textUndoHistoryRegistry          = textUndoHistoryRegistry;
                _fileChangeTracker                = new FileChangeTracker(fileChangeService, this.FilePath);
                _fileChangeTracker.UpdatedOnDisk += OnUpdatedOnDisk;

                _openTextBuffer  = openTextBuffer;
                _snapshotTracker = new ReiteratedVersionSnapshotTracker(openTextBuffer);

                // The project system does not tell us the CodePage specified in the proj file, so
                // we use null to auto-detect.
                _doNotAccessDirectlyLoader = new FileTextLoader(documentKey.Moniker, defaultEncoding: null);

                // If we aren't already open in the editor, then we should create a file change notification
                if (openTextBuffer == null)
                {
                    _fileChangeTracker.StartFileChangeListeningAsync();
                }
            }
        public void TrackFilePathAndAddSolutionItemWhenFileCreated(string filePath)
        {
            if (_fileChangeService != null &&
                PathUtilities.IsAbsolute(filePath) &&
                FileExistsWithGuard(filePath) == false)
            {
                // Setup a new file change tracker to track file path and
                // add newly created file as solution item.
                _fileChangeTrackers.GetOrAdd(filePath, CreateTracker);
            }

            return;

            // Local functions
            FileChangeTracker CreateTracker(string filePath)
            {
                var tracker = new FileChangeTracker(_fileChangeService, filePath, _VSFILECHANGEFLAGS.VSFILECHG_Add);

                tracker.UpdatedOnDisk += OnFileAdded;
                tracker.StartFileChangeListeningAsync();
                return(tracker);
            }
        }
        private void AnalyzerFileReference_AssemblyLoad(object sender, AnalyzerAssemblyLoadEventArgs e)
        {
            lock (_guard)
            {
                FileChangeTracker tracker;
                if (!_fileChangeTrackers.TryGetValue(e.Path, out tracker))
                {
                    tracker = new FileChangeTracker(_fileChangeService, e.Path);
                    tracker.UpdatedOnDisk += Tracker_UpdatedOnDisk;
                    tracker.StartFileChangeListeningAsync();

                    _fileChangeTrackers.Add(e.Path, tracker);
                }

                DateTime? fileUpdateTime = GetLastUpdateTimeUtc(e.Path);

                if (fileUpdateTime.HasValue)
                {
                    _assemblyUpdatedTimesUtc[e.Path] = fileUpdateTime.Value;
                }
            }
        }
 public FileChangeTrackingTextLoader(FileChangeTracker fileChangeTracker, TextLoader innerTextLoader)
 {
     _fileChangeTracker = fileChangeTracker;
     _innerTextLoader   = innerTextLoader;
 }
        internal void AddPath(string filePath)
        {
            lock (_guard)
            {
                FileChangeTracker tracker;
                if (!_fileChangeTrackers.TryGetValue(filePath, out tracker))
                {
                    tracker = new FileChangeTracker(_fileChangeService, filePath);
                    tracker.UpdatedOnDisk += Tracker_UpdatedOnDisk;
                    tracker.StartFileChangeListeningAsync();

                    _fileChangeTrackers.Add(filePath, tracker);
                }

                DateTime? fileUpdateTime = GetLastUpdateTimeUtc(filePath);

                if (fileUpdateTime.HasValue)
                {
                    _assemblyUpdatedTimesUtc[filePath] = fileUpdateTime.Value;
                }
            }
        }
            public StandardTextDocument(
                DocumentProvider documentProvider,
                IVisualStudioHostProject project,
                DocumentKey documentKey,
                uint itemId,
                SourceCodeKind sourceCodeKind,
                ITextBufferFactoryService textBufferFactoryService,
                ITextUndoHistoryRegistry textUndoHistoryRegistry,
                IVsFileChangeEx fileChangeService,
                ITextBuffer openTextBuffer,
                DocumentId id)
            {
                Contract.ThrowIfNull(documentProvider);
                Contract.ThrowIfNull(textBufferFactoryService);

                this.Project = project;
                this.Id = id ?? DocumentId.CreateNewId(project.Id, documentKey.Moniker);
                this.Folders = project.GetFolderNames(itemId);

                // TODO: 
                // this one doesn't work for asynchronous project load situation where shared projects is loaded after one uses shared file. 
                // we need to figure out what to do on those case. but this works for project k case.
                // opened an issue to track this issue - https://github.com/dotnet/roslyn/issues/1859
                this.SharedHierarchy = project.Hierarchy == null ? null : LinkedFileUtilities.GetSharedHierarchyForItem(project.Hierarchy, itemId);
                _documentProvider = documentProvider;

                this.Key = documentKey;
                this.SourceCodeKind = sourceCodeKind;
                _itemMoniker = documentKey.Moniker;
                _textBufferFactoryService = textBufferFactoryService;
                _textUndoHistoryRegistry = textUndoHistoryRegistry;
                _fileChangeTracker = new FileChangeTracker(fileChangeService, this.FilePath);
                _fileChangeTracker.UpdatedOnDisk += OnUpdatedOnDisk;

                _openTextBuffer = openTextBuffer;
                _snapshotTracker = new ReiteratedVersionSnapshotTracker(openTextBuffer);

                // The project system does not tell us the CodePage specified in the proj file, so
                // we use null to auto-detect.
                _doNotAccessDirectlyLoader = new FileTextLoader(documentKey.Moniker, defaultEncoding: null);

                // If we aren't already open in the editor, then we should create a file change notification
                if (openTextBuffer == null)
                {
                    _fileChangeTracker.StartFileChangeListeningAsync();
                }
            }