public MonoDevelopMetadataReference(
            MonoDevelopMetadataReferenceManager provider,
            string filePath,
            MetadataReferenceProperties properties)
        {
            Contract.Requires(properties.Kind == MetadataImageKind.Assembly);

            FilePath    = filePath;
            _provider   = provider;
            _properties = properties;

            FileWatcherService.WatchDirectories(this, new [] { FilePath.ParentDirectory });
            FileService.FileChanged += OnUpdatedOnDisk;
        }
            public MonoDevelopMetadataReference GetOrCreate(MonoDevelopMetadataReferenceManager provider, string path, MetadataReferenceProperties properties)
            {
                if (properties == MetadataReferenceProperties.Assembly)
                {
                    // fast path for no custom properties
                    return(GetOrCreate(cacheAssemblyProperties, path, provider, path, properties));
                }

                Dictionary <MetadataReferenceProperties, MonoDevelopMetadataReference> dict;

                lock (cacheWithCustomProperties) {
                    if (!cacheWithCustomProperties.TryGetValue(path, out dict))
                    {
                        cacheWithCustomProperties [path] = dict = new Dictionary <MetadataReferenceProperties, MonoDevelopMetadataReference> ();
                    }
                }
                return(GetOrCreate(dict, properties, provider, path, properties));
            }
            internal Snapshot(MonoDevelopMetadataReferenceManager provider, MetadataReferenceProperties properties, string fullPath)
                : base(properties, fullPath)
            {
                Contract.Requires(Properties.Kind == MetadataImageKind.Assembly);
                _provider = provider;

                _timestamp = new Lazy <DateTime> (() => {
                    try {
                        return(Roslyn.Utilities.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 bool TryGetCachedItems(Project p, MonoDevelopMetadataReferenceManager provider, MonoDevelopWorkspace.ProjectDataMap projectMap,
                                      out ImmutableArray <ProjectFile> files,
                                      out ImmutableArray <FilePath> analyzers,
                                      out ImmutableArray <MonoDevelopMetadataReference> metadataReferences,
                                      out ImmutableArray <Microsoft.CodeAnalysis.ProjectReference> projectReferences)
        {
            files              = ImmutableArray <ProjectFile> .Empty;
            analyzers          = ImmutableArray <FilePath> .Empty;
            metadataReferences = ImmutableArray <MonoDevelopMetadataReference> .Empty;
            projectReferences  = ImmutableArray <Microsoft.CodeAnalysis.ProjectReference> .Empty;

            ProjectCache cachedData;

            lock (cachedItems) {
                if (!cachedItems.TryGetValue(p.FileName, out cachedData))
                {
                    return(false);
                }
            }

            var filesBuilder = ImmutableArray.CreateBuilder <ProjectFile> (cachedData.Files.Length);

            for (int i = 0; i < cachedData.Files.Length; ++i)
            {
                filesBuilder.Add(new ProjectFile(cachedData.Files [i], cachedData.BuildActions [i])
                {
                    Project = p,
                });
            }

            files = filesBuilder.MoveToImmutable();

            var analyzersBuilder = ImmutableArray.CreateBuilder <FilePath> (cachedData.Analyzers.Length);

            foreach (var analyzer in cachedData.Analyzers)
            {
                analyzersBuilder.Add(analyzer);
            }
            analyzers = analyzersBuilder.MoveToImmutable();

            var mrBuilder = ImmutableArray.CreateBuilder <MonoDevelopMetadataReference> (cachedData.MetadataReferences.Length);

            foreach (var item in cachedData.MetadataReferences)
            {
                var aliases = item.Aliases != null?item.Aliases.ToImmutableArray() : default;

                var reference = provider.GetOrCreateMetadataReference(item.FilePath, new Microsoft.CodeAnalysis.MetadataReferenceProperties(aliases: aliases));
                mrBuilder.Add(reference);
            }
            metadataReferences = mrBuilder.MoveToImmutable();

            var sol         = p.ParentSolution;
            var solConfig   = sol.GetConfiguration(IdeServices.Workspace.ActiveConfiguration);
            var allProjects = sol.GetAllProjects().ToDictionary(x => x.FileName, x => x);

            var prBuilder = ImmutableArray.CreateBuilder <Microsoft.CodeAnalysis.ProjectReference> (cachedData.ProjectReferences.Length);

            foreach (var item in cachedData.ProjectReferences)
            {
                if (!allProjects.TryGetValue(item.FilePath, out var mdProject))
                {
                    return(false);
                }

                var aliases = item.Aliases != null?item.Aliases.ToImmutableArray() : default;

                var pr = new Microsoft.CodeAnalysis.ProjectReference(projectMap.GetOrCreateId(mdProject, null), aliases.ToImmutableArray());
                prBuilder.Add(pr);
            }
            projectReferences = prBuilder.MoveToImmutable();
            return(true);
        }
 public bool TryGetCachedItems(Project p, MonoDevelopMetadataReferenceManager provider, MonoDevelopWorkspace.ProjectDataMap projectMap,
                               out ProjectCacheInfo info)
 {
     info = new ProjectCacheInfo();
     return(TryGetCachedItems(p, provider, projectMap, out info.SourceFiles, out info.AnalyzerFiles, out info.References, out info.ProjectReferences));
 }
 static MonoDevelopMetadataReference GetOrCreate <TKey> (Dictionary <TKey, MonoDevelopMetadataReference> cache, TKey key, MonoDevelopMetadataReferenceManager provider, string path, MetadataReferenceProperties properties)
 {
     lock (cache) {
         if (!cache.TryGetValue(key, out var result))
         {
             cache [key] = result = new MonoDevelopMetadataReference(provider, path, properties);
         }
         return(result);
     }
 }
 public MetadataReferenceHandler(MonoDevelopMetadataReferenceManager manager, ProjectDataMap projectMap)
 {
     this.manager    = manager;
     this.projectMap = projectMap;
 }
        public bool TryGetCachedItems(Project p, MonoDevelopMetadataReferenceManager provider, MonoDevelopWorkspace.ProjectDataMap projectMap, string framework,
                                      out ProjectCacheInfo info)
        {
            info = new ProjectCacheInfo();

            List <ProjectCache> cachedDataList;

            lock (cachedItems) {
                if (!cachedItems.TryGetValue(p.FileName, out cachedDataList))
                {
                    return(false);
                }
            }

            ProjectCache cachedData = cachedDataList.FirstOrDefault(cache => cache.Framework == framework);

            if (cachedData == null)
            {
                return(false);
            }

            var filesBuilder = ImmutableArray.CreateBuilder <ProjectFile> (cachedData.Files.Length);

            for (int i = 0; i < cachedData.Files.Length; ++i)
            {
                filesBuilder.Add(new ProjectFile(cachedData.Files [i], cachedData.BuildActions [i])
                {
                    Project = p,
                });
            }

            info.SourceFiles = filesBuilder.MoveToImmutable();

            info.AdditionalFiles   = ToImmutableFilePathArray(cachedData.AdditionalFiles);
            info.AnalyzerFiles     = ToImmutableFilePathArray(cachedData.Analyzers);
            info.EditorConfigFiles = ToImmutableFilePathArray(cachedData.EditorConfigFiles);

            var mrBuilder = ImmutableArray.CreateBuilder <MonoDevelopMetadataReference> (cachedData.MetadataReferences.Length);

            foreach (var item in cachedData.MetadataReferences)
            {
                var aliases = item.Aliases != null?item.Aliases.ToImmutableArray() : default;

                var reference = provider.GetOrCreateMetadataReference(item.FilePath, new Microsoft.CodeAnalysis.MetadataReferenceProperties(aliases: aliases));
                mrBuilder.Add(reference);
            }
            info.References = mrBuilder.MoveToImmutable();

            var sol         = p.ParentSolution;
            var solConfig   = sol.GetConfiguration(IdeServices.Workspace.ActiveConfiguration);
            var allProjects = sol.GetAllProjects().ToDictionary(x => x.FileName, x => x);

            var prBuilder = ImmutableArray.CreateBuilder <Microsoft.CodeAnalysis.ProjectReference> (cachedData.ProjectReferences.Length);

            foreach (var item in cachedData.ProjectReferences)
            {
                if (!allProjects.TryGetValue(item.FilePath, out var mdProject))
                {
                    return(false);
                }

                var aliases = item.Aliases != null?item.Aliases.ToImmutableArray() : default;

                var pr = new Microsoft.CodeAnalysis.ProjectReference(projectMap.GetOrCreateId(mdProject, null, item.Framework), aliases.ToImmutableArray());
                prBuilder.Add(pr);
            }
            info.ProjectReferences = prBuilder.MoveToImmutable();
            return(true);
        }