示例#1
0
        private MetadataShadowCopy GetMetadataShadowCopyNoCheck(string fullPath, MetadataImageKind kind)
        {
            if (kind < MetadataImageKind.Assembly || kind > MetadataImageKind.Module)
            {
                throw new ArgumentOutOfRangeException("kind");
            }

            FileKey key = FileKey.Create(fullPath);

            lock (Guard)
            {
                CacheEntry <MetadataShadowCopy> existing;
                if (CopyExistsOrIsSuppressed(key, out existing))
                {
                    return(existing.Public);
                }
            }

            CacheEntry <MetadataShadowCopy> newCopy = CreateMetadataShadowCopy(fullPath, kind);

            // last-write timestamp is copied from the original file at the time the snapshot was made:
            bool fault = true;

            try
            {
                key   = new FileKey(fullPath, FileUtilities.GetLastWriteTimeStamp(newCopy.Public.PrimaryModule.FullPath));
                fault = false;
            }
            finally
            {
                if (fault)
                {
                    newCopy.Private.Dispose();
                }
            }

            lock (Guard)
            {
                CacheEntry <MetadataShadowCopy> existing;
                if (CopyExistsOrIsSuppressed(key, out existing))
                {
                    newCopy.Private.Dispose();
                    return(existing.Public);
                }

                _shadowCopies.Add(key, newCopy);
            }

            return(newCopy.Public);
        }
示例#2
0
        /// <summary>
        /// Gets or creates metadata for specified file path.
        /// </summary>
        /// <param name="fullPath">Full path to an assembly manifest module file or a standalone module file.</param>
        /// <param name="kind">Metadata kind (assembly or module).</param>
        /// <returns>Metadata for the specified file.</returns>
        /// <exception cref="IOException">Error reading file <paramref name="fullPath"/>. See <see cref="Exception.InnerException"/> for details.</exception>
        public Metadata GetMetadata(string fullPath, MetadataImageKind kind)
        {
            if (NeedsShadowCopy(fullPath))
            {
                return(GetMetadataShadowCopyNoCheck(fullPath, kind).Metadata);
            }

            FileKey key = FileKey.Create(fullPath);

            lock (Guard)
            {
                CacheEntry <Metadata> existing;
                if (_noShadowCopyCache.TryGetValue(key, out existing))
                {
                    return(existing.Public);
                }
            }

            Metadata newMetadata;

            if (kind == MetadataImageKind.Assembly)
            {
                newMetadata = AssemblyMetadata.CreateFromFile(fullPath);
            }
            else
            {
                newMetadata = ModuleMetadata.CreateFromFile(fullPath);
            }

            // the files are locked (memory mapped) now
            key = FileKey.Create(fullPath);

            lock (Guard)
            {
                CacheEntry <Metadata> existing;
                if (_noShadowCopyCache.TryGetValue(key, out existing))
                {
                    newMetadata.Dispose();
                    return(existing.Public);
                }

                Metadata publicMetadata = newMetadata.Copy();
                _noShadowCopyCache.Add(key, new CacheEntry <Metadata>(publicMetadata, newMetadata));
                return(publicMetadata);
            }
        }
示例#3
0
        /// <exception cref="IOException"/>
        private static ModuleMetadata GetOrCreateModuleFromFile(string fullPath)
        {
            ModuleMetadata module = null;

            // may throw
            FileKey key = FileKey.Create(fullPath);

            CachedModule cachedModule;
            bool         existingKey = modulesFromFiles.TryGetValue(key, out cachedModule);

            if (existingKey && cachedModule.Metadata.TryGetTarget(out module))
            {
                return(module);
            }

            // mempy-map the module:
            module = ModuleMetadata.CreateFromFile(fullPath);

            // refresh the timestamp (the file may have changed just before we memory-mapped it):
            bool fault = true;

            try
            {
                key   = FileKey.Create(fullPath);
                fault = false;
            }
            finally
            {
                if (fault)
                {
                    module.Dispose();
                }
            }

            cachedModule          = new CachedModule(module);
            modulesFromFiles[key] = cachedModule;

            if (!existingKey)
            {
                moduleKeys.Add(key);
                EnableCompactTimer();
            }

            return(module);
        }
示例#4
0
        /// <exception cref="IOException"/>
        private static AssemblyMetadata GetOrCreateAssemblyFromFile(string fullPath)
        {
            AssemblyMetadata assembly = null;

            // may throw:
            FileKey key = FileKey.Create(fullPath);

            CachedAssembly cachedAssembly;
            bool           existingKey = assembliesFromFiles.TryGetValue(key, out cachedAssembly);

            if (existingKey && cachedAssembly.Metadata.TryGetTarget(out assembly))
            {
                return(assembly);
            }

            // memory-map all modules of the assembly:
            assembly = AssemblyMetadata.CreateFromFile(fullPath);

            // refresh the timestamp (the file may have changed just before we memory-mapped it):
            bool fault = true;

            try
            {
                key   = FileKey.Create(fullPath);
                fault = false;
            }
            finally
            {
                if (fault)
                {
                    assembly.Dispose();
                }
            }

            cachedAssembly           = new CachedAssembly(assembly);
            assembliesFromFiles[key] = cachedAssembly;

            if (!existingKey)
            {
                assemblyKeys.Add(key);
                EnableCompactTimer();
            }

            return(assembly);
        }
示例#5
0
        internal static ImmutableArray <DiagnosticAnalyzer> GetOrCreateAnalyzersFromFile(AnalyzerFileReference analyzerReference, string langauge = null)
        {
            string fullPath = analyzerReference.FullPath;

            Debug.Assert(PathUtilities.IsAbsolute(fullPath));

            lock (Guard)
            {
                // may throw:
                FileKey key = FileKey.Create(fullPath);

                CachedAnalyzers cachedAnalyzers;
                if (analyzersFromFiles.TryGetValue(key, out cachedAnalyzers))
                {
                    if (cachedAnalyzers.Analyzers.IsAlive && cachedAnalyzers.Language == langauge)
                    {
                        return((ImmutableArray <DiagnosticAnalyzer>)cachedAnalyzers.Analyzers.Target);
                    }
                    else
                    {
                        analyzersFromFiles.Remove(key);
                        var removed = analyzerAssemblyKeys.Remove(key);
                        Debug.Assert(removed);
                        Debug.Assert(!analyzerAssemblyKeys.Contains(key));
                    }
                }

                // get all analyzers in the assembly:
                var builder = ImmutableArray.CreateBuilder <DiagnosticAnalyzer>();
                analyzerReference.AddAnalyzers(builder, langauge);
                var analyzers = builder.ToImmutable();

                // refresh the timestamp (the file may have changed just before we memory-mapped it):
                key = FileKey.Create(fullPath);

                analyzersFromFiles[key] = new CachedAnalyzers(analyzers, langauge);
                Debug.Assert(!analyzerAssemblyKeys.Contains(key));
                analyzerAssemblyKeys.Add(key);
                EnableCompactTimer();

                return(analyzers);
            }
        }
示例#6
0
        private MetadataShadowCopy GetMetadataShadowCopyNoCheck(string fullPath, MetadataImageKind kind)
        {
            if (!kind.IsValid())
            {
                throw new ArgumentOutOfRangeException("kind");
            }

            FileKey key = new FileKey(fullPath);

            lock (Guard)
            {
                CacheEntry <MetadataShadowCopy> existing;
                if (CopyExistsOrIsSuppressed(key, out existing))
                {
                    return(existing.Public);
                }
            }

            CacheEntry <MetadataShadowCopy> newCopy = CreateMetadataShadowCopy(fullPath, kind);

            // last-write timestamp is copied from the original file at the time the snapshot was made:
            key = new FileKey(fullPath, FileKey.GetTimeStamp(newCopy.Public.PrimaryModule.FullPath));

            lock (Guard)
            {
                CacheEntry <MetadataShadowCopy> existing;
                if (CopyExistsOrIsSuppressed(key, out existing))
                {
                    newCopy.Private.Dispose();
                    return(existing.Public);
                }

                shadowCopies.Add(key, newCopy);
            }

            return(newCopy.Public);
        }