Example #1
0
        private static async Task VerifyOptionSetsAsync(Workspace workspace, string language)
        {
            var assetBuilder = new CustomAssetBuilder(workspace);
            var serializer   = new Serializer(workspace);

            var asset = assetBuilder.Build(workspace.Options, language, CancellationToken.None);

            using (var stream = SerializableBytes.CreateWritableStream())
                using (var writer = new StreamObjectWriter(stream))
                {
                    await asset.WriteObjectToAsync(writer, CancellationToken.None).ConfigureAwait(false);

                    stream.Position = 0;
                    using (var reader = StreamObjectReader.TryGetReader(stream))
                    {
                        var recovered        = serializer.Deserialize <OptionSet>(asset.Kind, reader, CancellationToken.None);
                        var assetFromStorage = assetBuilder.Build(recovered, language, CancellationToken.None);

                        Assert.Equal(asset.Checksum, assetFromStorage.Checksum);

                        // option should be exactly same
                        Assert.Equal(0, recovered.GetChangedOptions(workspace.Options).Count());
                    }
                }
        }
Example #2
0
        private static async Task <bool> PrecalculatedAsync(Document document, string persistenceName, string formatVersion, CancellationToken cancellationToken)
        {
            Contract.Requires(document.IsFromPrimaryBranch());

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

            // check whether we already have info for this document
            try
            {
                using (var storage = persistentStorageService.GetStorage(document.Project.Solution))
                    using (var stream = await storage.ReadStreamAsync(document, persistenceName, cancellationToken).ConfigureAwait(false))
                        using (var reader = StreamObjectReader.TryGetReader(stream))
                        {
                            if (reader != null)
                            {
                                return(TryReadVersion(reader, formatVersion, out var persistVersion) &&
                                       document.CanReusePersistedSyntaxTreeVersion(syntaxVersion, persistVersion));
                            }
                        }
            }
            catch (Exception e) when(IOUtilities.IsNormalIOException(e))
            {
                // Storage APIs can throw arbitrary exceptions.
            }

            return(false);
        }
        public async Task TestSymbolTreeInfoSerialization()
        {
            var solution    = GetSolution(WorkspaceKind.SingleClass);
            var compilation = await solution.Projects.First().GetCompilationAsync();

            var assembly = compilation.GetSpecialType(SpecialType.System_Byte).ContainingAssembly;
            ////var assembly = compilation.Assembly;

            // create symbol tree info from assembly
            var version = VersionStamp.Create();
            var info    = SymbolTreeInfo.CreateSourceSymbolTreeInfo(
                solution, version, assembly, "", cancellationToken: CancellationToken.None);

            using (var writerStream = new MemoryStream())
            {
                using (var writer = new StreamObjectWriter(writerStream))
                {
                    info.WriteTo(writer);
                }

                using (var readerStream = new MemoryStream(writerStream.ToArray()))
                    using (var reader = StreamObjectReader.TryGetReader(readerStream))
                    {
                        var readInfo = SymbolTreeInfo.ReadSymbolTreeInfo_ForTestingPurposesOnly(reader);

                        info.AssertEquivalentTo(readInfo);
                    }
            }
        }
Example #4
0
        private static async Task <SyntaxTreeIndex> LoadAsync(
            Document document, string persistenceName, string formatVersion,
            Func <ObjectReader, VersionStamp, SyntaxTreeIndex> readFrom, CancellationToken cancellationToken)
        {
            var persistentStorageService = document.Project.Solution.Workspace.Services.GetService <IPersistentStorageService>();
            var syntaxVersion            = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false);

            try
            {
                // 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))
                        using (var reader = StreamObjectReader.TryGetReader(stream))
                        {
                            if (reader != null)
                            {
                                if (TryReadVersion(reader, formatVersion, out var persistVersion) &&
                                    document.CanReusePersistedSyntaxTreeVersion(syntaxVersion, persistVersion))
                                {
                                    return(readFrom(reader, syntaxVersion));
                                }
                            }
                        }
            }
            catch (Exception e) when(IOUtilities.IsNormalIOException(e))
            {
                // Storage APIs can throw arbitrary exceptions.
            }

            return(null);
        }
Example #5
0
            private IList <ValueTuple <Checksum, object> > ReadAssets(
                Stream stream, int sessionId, ISet <Checksum> checksums, CancellationToken cancellationToken)
            {
                var results = new List <ValueTuple <Checksum, object> >();

                using (var reader = StreamObjectReader.TryGetReader(stream))
                {
                    Debug.Assert(reader != null,
                                 @"We only ge a reader for data transmitted between live processes.
This data should always be correct as we're never persisting the data between sessions.");

                    var responseSessionId = reader.ReadInt32();
                    Contract.ThrowIfFalse(sessionId == responseSessionId);

                    var count = reader.ReadInt32();
                    Contract.ThrowIfFalse(count == checksums.Count);

                    for (var i = 0; i < count; i++)
                    {
                        var responseChecksum = new Checksum(reader.ReadArray <byte>());
                        Contract.ThrowIfFalse(checksums.Contains(responseChecksum));

                        var kind = reader.ReadString();

                        // in service hub, cancellation means simply closed stream
                        var @object = _owner.RoslynServices.AssetService.Deserialize <object>(kind, reader, cancellationToken);

                        results.Add(ValueTuple.Create(responseChecksum, @object));
                    }

                    return(results);
                }
            }
Example #6
0
        private void TestInvalidStreamVersion()
        {
            var stream = new MemoryStream();

            stream.WriteByte(0);
            stream.WriteByte(0);

            stream.Position = 0;

            var reader = StreamObjectReader.TryGetReader(stream);

            Assert.Null(reader);
        }
Example #7
0
        private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > GetCompilerAnalysisResultAsync(Stream stream, Dictionary <string, DiagnosticAnalyzer> analyzerMap, Project project, CancellationToken cancellationToken)
        {
            // handling of cancellation and exception
            var version = await DiagnosticIncrementalAnalyzer.GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false);

            using (var reader = StreamObjectReader.TryGetReader(stream))
            {
                Debug.Assert(reader != null,
                             @"We only ge a reader for data transmitted between live processes.
This data should always be correct as we're never persisting the data between sessions.");
                return(DiagnosticResultSerializer.Deserialize(reader, analyzerMap, project, version, cancellationToken));
            }
        }
Example #8
0
        public void VersionStamp_RoundTripText()
        {
            using (var writerStream = new MemoryStream())
                using (var writer = new StreamObjectWriter(writerStream))
                {
                    var versionStamp = VersionStamp.Create();
                    versionStamp.WriteTo(writer);

                    using (var readerStream = new MemoryStream(writerStream.ToArray()))
                        using (var reader = StreamObjectReader.TryGetReader(readerStream))
                        {
                            var deserializedVersionStamp = VersionStamp.ReadFrom(reader);

                            Assert.Equal(versionStamp, deserializedVersionStamp);
                        }
                }
        }
Example #9
0
        private static async Task <RemotableData> CloneAssetAsync(Serializer serializer, RemotableData asset)
        {
            using (var stream = SerializableBytes.CreateWritableStream())
                using (var writer = new StreamObjectWriter(stream))
                {
                    await asset.WriteObjectToAsync(writer, CancellationToken.None).ConfigureAwait(false);

                    stream.Position = 0;
                    using (var reader = StreamObjectReader.TryGetReader(stream))
                    {
                        var recovered        = serializer.Deserialize <object>(asset.Kind, reader, CancellationToken.None);
                        var assetFromStorage = SolutionAsset.Create(serializer.CreateChecksum(recovered, CancellationToken.None), recovered, serializer);

                        Assert.Equal(asset.Checksum, assetFromStorage.Checksum);
                        return(assetFromStorage);
                    }
                }
        }
Example #10
0
        public void TestSerialization()
        {
            var stream      = new MemoryStream();
            var bloomFilter = new BloomFilter(0.001, false, new[] { "Hello, World" });

            using (var writer = new StreamObjectWriter(stream))
            {
                bloomFilter.WriteTo(writer);
            }

            stream.Position = 0;

            using (var reader = StreamObjectReader.TryGetReader(stream))
            {
                var rehydratedFilter = BloomFilter.ReadFrom(reader);
                Assert.True(bloomFilter.IsEquivalent(rehydratedFilter));
            }
        }
Example #11
0
        private T RoundTrip <T>(T value, Action <ObjectWriter, T> writeAction, Func <ObjectReader, T> readAction, bool recursive)
        {
            var stream = new MemoryStream();
            var binder = new RecordingObjectBinder();
            var writer = new StreamObjectWriter(stream, binder: binder, recursive: recursive);

            writeAction(writer, value);
            writer.Dispose();

            stream.Position = 2;
            Assert.Equal(recursive, StreamObjectReader.IsRecursive(stream));

            stream.Position = 0;
            using (var reader = StreamObjectReader.TryGetReader(stream, binder: binder))
            {
                return((T)readAction(reader));
            }
        }
Example #12
0
        public async Task <StrongBox <ImmutableArray <DiagnosticData> > > DeserializeAsync(object documentOrProject, string key, CancellationToken cancellationToken)
        {
            // we have persisted data
            var solution       = GetSolution(documentOrProject);
            var persistService = solution.Workspace.Services.GetService <IPersistentStorageService>();

            using (var storage = persistService.GetStorage(solution))
                using (var stream = await ReadStreamAsync(storage, key, documentOrProject, cancellationToken).ConfigureAwait(false))
                    using (var reader = StreamObjectReader.TryGetReader(stream))
                    {
                        if (reader == null)
                        {
                            return(null);
                        }

                        // we return StrongBox rather than ImmutableArray due to task lib's issue with allocations
                        // when returning default(value type)
                        return(ReadFrom(reader, documentOrProject, cancellationToken));
                    }
        }
Example #13
0
        public static async Task <T> GetValueAsync <T>(this ISolutionSynchronizationService service, Checksum checksum)
        {
            var syncService = (SolutionSynchronizationServiceFactory.Service)service;
            var syncObject  = service.GetRemotableData(checksum, CancellationToken.None);

            using (var stream = SerializableBytes.CreateWritableStream())
                using (var writer = new StreamObjectWriter(stream))
                {
                    // serialize asset to bits
                    await syncObject.WriteObjectToAsync(writer, CancellationToken.None).ConfigureAwait(false);

                    stream.Position = 0;
                    using (var reader = StreamObjectReader.TryGetReader(stream))
                    {
                        // deserialize bits to object
                        var serializer = syncService.Serializer_TestOnly;
                        return(serializer.Deserialize <T>(syncObject.Kind, reader, CancellationToken.None));
                    }
                }
        }
            protected override Data TryGetExistingData(Stream stream, Document value, CancellationToken cancellationToken)
            {
                using (var reader = StreamObjectReader.TryGetReader(stream))
                {
                    if (reader != null)
                    {
                        var format = reader.ReadString();
                        if (string.Equals(format, FormatVersion, StringComparison.InvariantCulture))
                        {
                            var textVersion = VersionStamp.ReadFrom(reader);
                            var dataVersion = VersionStamp.ReadFrom(reader);
                            var designerAttributeArgument = reader.ReadString();

                            return(new Data(textVersion, dataVersion, designerAttributeArgument));
                        }
                    }
                }

                return(null);
            }
Example #15
0
        public void TestObjectMapLimits()
        {
            using (var stream = new MemoryStream())
            {
                var instances = new List <TypeWithTwoMembers <int, string> >();

                // We need enough items to exercise all sizes of ObjectRef
                for (int i = 0; i < ushort.MaxValue + 1; i++)
                {
                    instances.Add(new TypeWithTwoMembers <int, string>(i, i.ToString()));
                }

                var binder = new RecordingObjectBinder();
                var writer = new StreamObjectWriter(stream, binder: binder);
                // Write each instance twice. The second time around, they'll become ObjectRefs
                for (int pass = 0; pass < 2; pass++)
                {
                    foreach (var instance in instances)
                    {
                        writer.WriteValue(instance);
                    }
                }

                writer.Dispose();

                stream.Position = 0;
                using (var reader = StreamObjectReader.TryGetReader(stream, binder: binder))
                {
                    for (int pass = 0; pass < 2; pass++)
                    {
                        foreach (var instance in instances)
                        {
                            var obj = reader.ReadValue();
                            Assert.NotNull(obj);
                            Assert.True(Equalish(obj, instance));
                        }
                    }
                }
            }
        }
Example #16
0
            protected override Data TryGetExistingData(Stream stream, Document value, CancellationToken cancellationToken)
            {
                using (var reader = StreamObjectReader.TryGetReader(stream))
                {
                    if (reader != null)
                    {
                        var format = reader.ReadString();
                        if (string.Equals(format, FormatVersion))
                        {
                            var textVersion = VersionStamp.ReadFrom(reader);
                            var dataVersion = VersionStamp.ReadFrom(reader);

                            var list = ArrayBuilder <TodoItem> .GetInstance();

                            AppendItems(reader, value, list, cancellationToken);

                            return(new Data(textVersion, dataVersion, list.ToImmutableAndFree()));
                        }
                    }
                }

                return(null);
            }
Example #17
0
        private static bool TryReadFrom(Project project, string keyName, out Versions versions)
        {
            versions = default(Versions);

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

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

            try
            {
                using (var storage = service.GetStorage(project.Solution))
                    using (var stream = storage.ReadStreamAsync(keyName, CancellationToken.None).WaitAndGetResult(CancellationToken.None))
                        using (var reader = StreamObjectReader.TryGetReader(stream))
                        {
                            if (reader != null)
                            {
                                var formatVersion = reader.ReadInt32();
                                if (formatVersion == SerializationFormat)
                                {
                                    var persistedProjectVersion  = VersionStamp.ReadFrom(reader);
                                    var persistedSemanticVersion = VersionStamp.ReadFrom(reader);

                                    versions = new Versions(persistedProjectVersion, persistedSemanticVersion);
                                    return(true);
                                }
                            }
                        }
            }
            catch (Exception e) when(IOUtilities.IsNormalIOException(e))
            {
            }

            return(false);
        }
Example #18
0
        /// <summary>
        /// Deserialize a syntax node from the byte stream.
        /// </summary>
        public static SyntaxNode DeserializeFrom(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanRead)
            {
                throw new InvalidOperationException(CodeAnalysisResources.TheStreamCannotBeReadFrom);
            }


            using (var reader = StreamObjectReader.TryGetReader(stream, knownObjects: GetDeserializationObjectData(), binder: s_defaultBinder, cancellationToken: cancellationToken))
            {
                if (reader == null)
                {
                    throw new ArgumentException(CodeAnalysisResources.Stream_contains_invalid_data, nameof(stream));
                }

                var root = (Syntax.InternalSyntax.CSharpSyntaxNode)reader.ReadValue();
                return(root.CreateRed());
            }
        }
Example #19
0
        /// <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.
            if (ShouldCreateFromScratch(solution, filePath, out var prefix, out var 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))
                    using (var reader = StreamObjectReader.TryGetReader(stream))
                    {
                        if (reader != null)
                        {
                            // 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 StreamObjectWriter(stream, cancellationToken: cancellationToken))
                        {
                            writeObject(writer, result);
                            stream.Position = 0;

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

            return(result);
        }