Esempio n. 1
0
        public static bool CanReusePersistedTextVersion(this Document document, VersionStamp textVersion, VersionStamp persistedVersion)
        {
            var canReuse = VersionStamp.CanReusePersistedVersion(textVersion, persistedVersion);

            PersistedVersionStampLogger.LogPersistedTextVersionUsage(canReuse);
            return(canReuse);
        }
        protected static async Task <T> LoadAsync <T>(
            Document document, string persistenceName, string formatVersion,
            Func <ObjectReader, VersionStamp, T> readFrom, CancellationToken cancellationToken) where T : AbstractPersistableState
        {
            var persistentStorageService = WorkspaceService.GetService <IPersistentStorageService>(document.Project.Solution.Workspace);
            var version = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false);

            // attempt to load from persisted state
            using (var storage = persistentStorageService.GetStorage(document.Project.Solution))
                using (var stream = await storage.ReadStreamAsync(document, persistenceName, cancellationToken).ConfigureAwait(false))
                {
                    if (stream == null)
                    {
                        return(null);
                    }

                    using (var reader = new ObjectReader(stream))
                    {
                        VersionStamp persistVersion;
                        if (TryReadVersion(reader, formatVersion, out persistVersion) &&
                            VersionStamp.CanReusePersistedVersion(version, persistVersion))
                        {
                            return(readFrom(reader, version));
                        }
                    }
                }

            return(null);
        }
Esempio n. 3
0
        public static bool CanReusePersistedDependentProjectVersion(this Project project, VersionStamp dependentProjectVersion, VersionStamp persistedVersion)
        {
            var canReuse = VersionStamp.CanReusePersistedVersion(dependentProjectVersion, persistedVersion);

            PersistedVersionStampLogger.LogPersistedDependentProjectVersionUsage(canReuse);
            return(canReuse);
        }
Esempio n. 4
0
        private static bool CanReusePersistedSemanticVersionInternal(
            Project project,
            VersionStamp projectVersion,
            VersionStamp semanticVersion,
            VersionStamp persistedVersion,
            Func <ISemanticVersionTrackingService, Project, VersionStamp, VersionStamp> versionGetter)
        {
            var canReuse = VersionStamp.CanReusePersistedVersion(semanticVersion, persistedVersion);

            if (canReuse)
            {
                return(true);
            }

            var service = project.Solution.Workspace.Services.GetService <ISemanticVersionTrackingService>();

            if (service == null)
            {
                return(canReuse);
            }

            var persistedProjectVersion = versionGetter(service, project, persistedVersion);

            return(VersionStamp.CanReusePersistedVersion(projectVersion, persistedProjectVersion));
        }
Esempio n. 5
0
        /// <summary>
        /// this is for a metadata reference in a solution
        /// </summary>
        private static async Task <SymbolTreeInfo> LoadOrCreateAsync(Solution solution, IAssemblySymbol assembly, string filePath, CancellationToken cancellationToken)
        {
            // if assembly is not from a file, just create one on the fly
            if (filePath == null || !File.Exists(filePath) || !FilePathUtilities.PartOfFrameworkOrReferencePaths(filePath))
            {
                return(Create(VersionStamp.Default, assembly, cancellationToken));
            }

            // if solution is not from a disk, just create one.
            if (solution.FilePath == null || !File.Exists(solution.FilePath))
            {
                return(Create(VersionStamp.Default, assembly, cancellationToken));
            }

            // okay, see whether we can get one from persistence service.
            var relativePath = FilePathUtilities.GetRelativePath(solution.FilePath, filePath);
            var version      = VersionStamp.Create(File.GetLastWriteTimeUtc(filePath));

            var persistentStorageService = solution.Workspace.Services.GetService <IPersistentStorageService>();

            // attempt to load from persisted state. metadata reference is solution wise information
            SymbolTreeInfo info;

            using (var storage = persistentStorageService.GetStorage(solution))
            {
                var key = PrefixMetadataSymbolTreeInfo + relativePath;
                using (var stream = await storage.ReadStreamAsync(key, cancellationToken).ConfigureAwait(false))
                {
                    if (stream != null)
                    {
                        using (var reader = new ObjectReader(stream))
                        {
                            info = ReadFrom(reader);
                            if (info != null && VersionStamp.CanReusePersistedVersion(version, info.version))
                            {
                                return(info);
                            }
                        }
                    }
                }

                cancellationToken.ThrowIfCancellationRequested();

                // compute it if we couldn't load it from cache
                info = Create(version, assembly, cancellationToken);
                if (info != null)
                {
                    using (var stream = SerializableBytes.CreateWritableStream())
                        using (var writer = new ObjectWriter(stream, cancellationToken: cancellationToken))
                        {
                            info.WriteTo(writer);
                            stream.Position = 0;

                            await storage.WriteStreamAsync(key, stream, cancellationToken).ConfigureAwait(false);
                        }
                }
            }

            return(info);
        }
Esempio n. 6
0
        public static bool CanReusePersistedSyntaxTreeVersion(this Document document, VersionStamp syntaxVersion, VersionStamp persistedVersion)
        {
            var canReuse = VersionStamp.CanReusePersistedVersion(syntaxVersion, persistedVersion);

            PersistedVersionStampLogger.LogPersistedSyntaxTreeVersionUsage(canReuse);
            return(canReuse);
        }
Esempio n. 7
0
        private static bool CheckSemanticVersions(Project project, AnalysisData existingData, VersionArgument versions)
        {
            if (existingData == null)
            {
                return(false);
            }

            return(VersionStamp.CanReusePersistedVersion(versions.TextVersion, existingData.TextVersion) &&
                   project.CanReusePersistedDependentSemanticVersion(versions.ProjectVersion, versions.DataVersion, existingData.DataVersion));
        }
Esempio n. 8
0
        /// <summary>
        /// this is for a project in a solution
        /// </summary>
        private static async Task <ValueTuple <bool, SymbolTreeInfo> > LoadOrCreateAsync(Project project, CancellationToken cancellationToken)
        {
            if (await project.IsForkedProjectWithSemanticChangesAsync(cancellationToken).ConfigureAwait(false))
            {
                return(ValueTuple.Create(false, await CreateAsync(project, cancellationToken).ConfigureAwait(false)));
            }

            var persistentStorageService = WorkspaceService.GetService <IPersistentStorageService>(project.Solution.Workspace);
            var version = await project.GetSemanticVersionAsync(cancellationToken).ConfigureAwait(false);

            // attempt to load from persisted state
            SymbolTreeInfo info;
            var            succeeded = false;

            using (var storage = persistentStorageService.GetStorage(project.Solution))
            {
                using (var stream = await storage.ReadStreamAsync(project, ProjectSymbolTreeInfoPersistenceName, cancellationToken).ConfigureAwait(false))
                {
                    if (stream != null)
                    {
                        using (var reader = new ObjectReader(stream))
                        {
                            info = ReadFrom(reader);
                            if (info != null && VersionStamp.CanReusePersistedVersion(version, info.version))
                            {
                                return(ValueTuple.Create(true, info));
                            }
                        }
                    }
                }

                cancellationToken.ThrowIfCancellationRequested();

                // compute it if we couldn't load it from cache
                info = await CreateAsync(project, cancellationToken).ConfigureAwait(false);

                if (info != null)
                {
                    using (var stream = SerializableBytes.CreateWritableStream())
                        using (var writer = new ObjectWriter(stream, cancellationToken: cancellationToken))
                        {
                            info.WriteTo(writer);
                            stream.Position = 0;

                            succeeded = await storage.WriteStreamAsync(project, ProjectSymbolTreeInfoPersistenceName, stream, cancellationToken).ConfigureAwait(false);
                        }
                }
            }

            return(ValueTuple.Create(succeeded, info));
        }
Esempio n. 9
0
        public VersionStamp GetInitialDependentProjectVersionFromDependentSemanticVersion(Project project, VersionStamp dependentSemanticVersion)
        {
            if (!TryGetInitialVersions(s_initialDependentSemanticVersions, project, DependentSemanticVersion, out var versions))
            {
                return(VersionStamp.Default);
            }

            if (!VersionStamp.CanReusePersistedVersion(dependentSemanticVersion, versions.SemanticVersion))
            {
                return(VersionStamp.Default);
            }

            return(versions.ProjectVersion);
        }
Esempio n. 10
0
 private static bool CanReusePersistedSemanticVersionInternal(
     Project project,
     VersionStamp projectVersion,
     VersionStamp semanticVersion,
     VersionStamp persistedVersion,
     Func <ISemanticVersionTrackingService, Project, VersionStamp, VersionStamp> versionGetter)
 {
     // * NOTE *
     // Disabled semantic version tracking
     // we need better version for it to reliably work.
     //
     // see tracking issue here : https://github.com/dotnet/roslyn/issues/2311
     return(VersionStamp.CanReusePersistedVersion(semanticVersion, persistedVersion));
 }
        public VersionStamp GetInitialProjectVersionFromSemanticVersion(Project project, VersionStamp semanticVersion)
        {
            Versions versions;

            if (!TryGetInitialVersions(s_initialSemanticVersions, project, SemanticVersion, out versions))
            {
                return(VersionStamp.Default);
            }

            if (!VersionStamp.CanReusePersistedVersion(semanticVersion, versions.SemanticVersion))
            {
                return(VersionStamp.Default);
            }

            return(versions.ProjectVersion);
        }
        public static async Task <bool> IdentifierSetPrecalculatedAsync(Document document, CancellationToken cancellationToken)
        {
            var version = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false);

            var persistentStorageService = WorkspaceService.GetService <IPersistentStorageService>(document.Project.Solution.Workspace);

            using (var storage = persistentStorageService.GetStorage(document.Project.Solution))
            {
                var esentStorage = storage as ISyntaxTreeInfoPersistentStorage;
                if (esentStorage == null)
                {
                    // basically, we don't support it. return true so that we don't try to precalcuate it
                    return(true);
                }

                var persistedVersion = esentStorage.GetIdentifierSetVersion(document);
                return(VersionStamp.CanReusePersistedVersion(version, persistedVersion));
            }
        }
        internal static async Task <ImmutableDictionary <string, DesignerAttributeDocumentData> > TryAnalyzeProjectInCurrentProcessAsync(
            Project project, CancellationToken cancellationToken)
        {
            var projectVersion = await project.GetDependentVersionAsync(cancellationToken).ConfigureAwait(false);

            var semanticVersion = await project.GetDependentSemanticVersionAsync(cancellationToken).ConfigureAwait(false);

            // Get whatever data we've current persisted.
            var designerAttributeData = await DesignerAttributeProjectData.ReadAsync(
                project, cancellationToken).ConfigureAwait(false);

            // If we have no persisted data, or the persisted data is for a previous version of
            // the project, then compute the results for the current project snapshot.
            if (designerAttributeData == null ||
                !VersionStamp.CanReusePersistedVersion(semanticVersion, designerAttributeData.SemanticVersion))
            {
                designerAttributeData = await ComputeAndPersistDesignerAttributeProjectDataAsync(
                    project, semanticVersion, cancellationToken).ConfigureAwait(false);
            }

            return(designerAttributeData.PathToDocumentData);
        }
        protected static async Task <bool> PrecalculatedAsync(Document document, string persistenceName, string formatVersion, CancellationToken cancellationToken)
        {
            Contract.Requires(document.IsFromPrimaryBranch());

            var persistentStorageService = WorkspaceService.GetService <IPersistentStorageService>(document.Project.Solution.Workspace);
            var version = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false);

            // check whether we already have info for this document
            using (var storage = persistentStorageService.GetStorage(document.Project.Solution))
                using (var stream = await storage.ReadStreamAsync(document, persistenceName, cancellationToken).ConfigureAwait(false))
                {
                    if (stream != null)
                    {
                        using (var reader = new ObjectReader(stream))
                        {
                            VersionStamp persistVersion;
                            return(TryReadVersion(reader, formatVersion, out persistVersion) &&
                                   VersionStamp.CanReusePersistedVersion(version, persistVersion));
                        }
                    }
                }

            return(false);
        }
        /// <summary>
        /// Generalized function for loading/creating/persisting data.  Used as the common core
        /// code for serialization of SymbolTreeInfos and SpellCheckers.
        /// </summary>
        private static async Task <T> LoadOrCreateAsync <T>(
            Solution solution,
            string filePath,
            bool loadOnly,
            Func <VersionStamp, T> create,
            string keySuffix,
            Func <T, VersionStamp> getVersion,
            Func <ObjectReader, T> readObject,
            Action <ObjectWriter, T> writeObject,
            CancellationToken cancellationToken) where T : class
        {
            // See if we can even use serialization.  If not, we'll just have to make the value
            // from scratch.
            string       prefix;
            VersionStamp version;

            if (ShouldCreateFromScratch(solution, filePath, out prefix, out version, cancellationToken))
            {
                return(loadOnly ? null : create(VersionStamp.Default));
            }

            // Ok, we can use persistence.  First try to load from the persistence service.
            var persistentStorageService = solution.Workspace.Services.GetService <IPersistentStorageService>();

            T result;

            using (var storage = persistentStorageService.GetStorage(solution))
            {
                // Get the unique key to identify our data.
                var key = PrefixMetadataSymbolTreeInfo + prefix + keySuffix;
                using (var stream = await storage.ReadStreamAsync(key, cancellationToken).ConfigureAwait(false))
                {
                    if (stream != null)
                    {
                        using (var reader = new ObjectReader(stream))
                        {
                            // We have some previously persisted data.  Attempt to read it back.
                            // If we're able to, and the version of the persisted data matches
                            // our version, then we can reuse this instance.
                            result = readObject(reader);
                            if (result != null && VersionStamp.CanReusePersistedVersion(version, getVersion(result)))
                            {
                                return(result);
                            }
                        }
                    }
                }

                cancellationToken.ThrowIfCancellationRequested();

                // Couldn't read from the persistence service.  If we've been asked to only load
                // data and not create new instances in their absense, then there's nothing left
                // to do at this point.
                if (loadOnly)
                {
                    return(null);
                }

                // Now, try to create a new instance and write it to the persistence service.
                result = create(version);
                if (result != null)
                {
                    using (var stream = SerializableBytes.CreateWritableStream())
                        using (var writer = new ObjectWriter(stream, cancellationToken: cancellationToken))
                        {
                            writeObject(writer, result);
                            stream.Position = 0;

                            await storage.WriteStreamAsync(key, stream, cancellationToken).ConfigureAwait(false);
                        }
                }
            }

            return(result);
        }
Esempio n. 16
0
        /// <summary>
        /// this is for a metadata reference in a solution
        /// </summary>
        private static async Task <SymbolTreeInfo> LoadOrCreateAsync(Solution solution, IAssemblySymbol assembly, string filePath, CancellationToken cancellationToken)
        {
            var service = solution.Workspace.Services.GetService <IAssemblySerializationInfoService>();

            if (service == null)
            {
                return(Create(VersionStamp.Default, assembly, cancellationToken));
            }

            // check whether the assembly that belong to a solution is something we can serialize
            if (!service.Serializable(solution, filePath))
            {
                return(Create(VersionStamp.Default, assembly, cancellationToken));
            }

            string       prefix;
            VersionStamp version;

            if (!service.TryGetSerializationPrefixAndVersion(solution, filePath, out prefix, out version))
            {
                return(Create(VersionStamp.Default, assembly, cancellationToken));
            }

            var persistentStorageService = solution.Workspace.Services.GetService <IPersistentStorageService>();

            // okay, see whether we can get one from persistence service.
            // attempt to load from persisted state. metadata reference is solution wise information
            SymbolTreeInfo info;

            using (var storage = persistentStorageService.GetStorage(solution))
            {
                var key = PrefixMetadataSymbolTreeInfo + prefix;
                using (var stream = await storage.ReadStreamAsync(key, cancellationToken).ConfigureAwait(false))
                {
                    if (stream != null)
                    {
                        using (var reader = new ObjectReader(stream))
                        {
                            info = ReadFrom(reader);
                            if (info != null && VersionStamp.CanReusePersistedVersion(version, info.version))
                            {
                                return(info);
                            }
                        }
                    }
                }

                cancellationToken.ThrowIfCancellationRequested();

                // compute it if we couldn't load it from cache
                info = Create(version, assembly, cancellationToken);
                if (info != null)
                {
                    using (var stream = SerializableBytes.CreateWritableStream())
                        using (var writer = new ObjectWriter(stream, cancellationToken: cancellationToken))
                        {
                            info.WriteTo(writer);
                            stream.Position = 0;

                            await storage.WriteStreamAsync(key, stream, cancellationToken).ConfigureAwait(false);
                        }
                }
            }

            return(info);
        }