public ComHandle <EnvDTE80.FileCodeModel2, FileCodeModel> GetOrCreateFileCodeModel( string filePath, object parent ) { // First try { var cacheEntry = GetCacheEntry(filePath); if (cacheEntry != null) { var comHandle = cacheEntry.Value.ComHandle; if (comHandle != null) { return(comHandle.Value); } } } // Check that we know about this file! var documentId = _state.Workspace.CurrentSolution .GetDocumentIdsWithFilePath(filePath) .Where(id => id.ProjectId == _projectId) .FirstOrDefault(); if (documentId == null) { // Matches behavior of native (C#) implementation throw Exceptions.ThrowENotImpl(); } // Create object (outside of lock) var newFileCodeModel = FileCodeModel.Create( _state, parent, documentId, new TextManagerAdapter() ); var newCacheEntry = new CacheEntry(newFileCodeModel); // Second try (object might have been added by another thread at this point!) lock (_cacheGate) { var cacheEntry = GetCacheEntry(filePath); if (cacheEntry != null) { var comHandle = cacheEntry.Value.ComHandle; if (comHandle != null) { return(comHandle.Value); } } // Note: Using the indexer here (instead of "Add") is relevant since the old // WeakReference entry is likely still in the cache (with a Null target, of course) _cache[filePath] = newCacheEntry; return(newFileCodeModel); } }
public EnvDTE.FileCodeModel CreateFileCodeModel(SourceGeneratedDocument sourceGeneratedDocument) { // Unlike for "regular" documents, we make no effort to cache these between callers or hold them for longer lifetimes with // events. return(FileCodeModel.Create(GetCodeModelCache().State, parent: null, sourceGeneratedDocument.Id, isSourceGeneratorOutput: true, new TextManagerAdapter()).Handle); }