private Solution( BranchId branchId, int workspaceVersion, SolutionServices solutionServices, SolutionId id, string filePath, ImmutableList<ProjectId> projectIds, ImmutableDictionary<ProjectId, ProjectState> idToProjectStateMap, ImmutableDictionary<ProjectId, CompilationTracker> projectIdToTrackerMap, ProjectDependencyGraph dependencyGraph, VersionStamp version, Lazy<VersionStamp> lazyLatestProjectVersion) { this.branchId = branchId; this.workspaceVersion = workspaceVersion; this.id = id; this.filePath = filePath; this.solutionServices = solutionServices; this.projectIds = projectIds; this.projectIdToProjectStateMap = idToProjectStateMap; this.projectIdToTrackerMap = projectIdToTrackerMap; this.dependencyGraph = dependencyGraph; this.projectIdToProjectMap = ImmutableHashMap<ProjectId, Project>.Empty; this.version = version; this.lazyLatestProjectVersion = lazyLatestProjectVersion; CheckInvariants(); }
private ProjectState( ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices, IEnumerable<DocumentId> documentIds, IEnumerable<DocumentId> additionalDocumentIds, ImmutableDictionary<DocumentId, DocumentState> documentStates, ImmutableDictionary<DocumentId, TextDocumentState> additionalDocumentStates, AsyncLazy<VersionStamp> lazyLatestDocumentVersion, AsyncLazy<VersionStamp> lazyLatestDocumentTopLevelChangeVersion, ValueSource<ProjectStateChecksums> lazyChecksums) { _projectInfo = projectInfo; _solutionServices = solutionServices; _languageServices = languageServices; _documentIds = documentIds.ToImmutableReadOnlyListOrEmpty(); _additionalDocumentIds = additionalDocumentIds.ToImmutableReadOnlyListOrEmpty(); _documentStates = documentStates; _additionalDocumentStates = additionalDocumentStates; _lazyLatestDocumentVersion = lazyLatestDocumentVersion; _lazyLatestDocumentTopLevelChangeVersion = lazyLatestDocumentTopLevelChangeVersion; // for now, let it re-calculate if anything changed. // TODO: optimize this so that we only re-calcuate checksums that are actually changed _lazyChecksums = new AsyncLazy<ProjectStateChecksums>(ComputeChecksumsAsync, cacheResult: true); }
public static DocumentState Create( DocumentInfo info, ParseOptions options, HostLanguageServices language, SolutionServices services) { var textSource = info.TextLoader != null ? CreateRecoverableText(info.TextLoader, info.Id, services) : CreateStrongText(TextAndVersion.Create(SourceText.From(string.Empty, Encoding.UTF8), VersionStamp.Default, info.FilePath)); var treeSource = CreateLazyFullyParsedTree( textSource, GetSyntaxTreeFilePath(info), options, languageServices: language); // remove any initial loader so we don't keep source alive info = info.WithTextLoader(null); return new DocumentState( languageServices: language, solutionServices: services, info: info, options: options, textSource: textSource, treeSource: treeSource); }
private SolutionState( BranchId branchId, int workspaceVersion, SolutionServices solutionServices, SolutionInfo solutionInfo, IEnumerable<ProjectId> projectIds, ImmutableDictionary<ProjectId, ProjectState> idToProjectStateMap, ImmutableDictionary<ProjectId, CompilationTracker> projectIdToTrackerMap, ImmutableDictionary<string, ImmutableArray<DocumentId>> linkedFilesMap, ProjectDependencyGraph dependencyGraph, Lazy<VersionStamp> lazyLatestProjectVersion) { _branchId = branchId; _workspaceVersion = workspaceVersion; _solutionServices = solutionServices; _solutionInfo = solutionInfo; _projectIds = projectIds.ToImmutableReadOnlyListOrEmpty(); _projectIdToProjectStateMap = idToProjectStateMap; _projectIdToTrackerMap = projectIdToTrackerMap; _linkedFilesMap = linkedFilesMap; _dependencyGraph = dependencyGraph; _lazyLatestProjectVersion = lazyLatestProjectVersion; // when solution state is changed, we re-calcuate its checksum _lazyChecksums = new AsyncLazy<SolutionStateChecksums>(ComputeChecksumsAsync, cacheResult: true); CheckInvariants(); }
protected static ValueSource<TextAndVersion> CreateRecoverableText(TextLoader loader, DocumentId documentId, SolutionServices services) { return new RecoverableTextAndVersion( new AsyncLazy<TextAndVersion>(c => LoadTextAsync(loader, documentId, services, c), cacheResult: false), services.TemporaryStorage, services.TextCache); }
public ProjectState(ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices) { Contract.ThrowIfNull(projectInfo); Contract.ThrowIfNull(languageServices); Contract.ThrowIfNull(solutionServices); _languageServices = languageServices; _solutionServices = solutionServices; _projectInfo = FixProjectInfo(projectInfo); _documentIds = _projectInfo.Documents.Select(d => d.Id).ToImmutableArray(); _additionalDocumentIds = _projectInfo.AdditionalDocuments.Select(d => d.Id).ToImmutableArray(); var docStates = ImmutableDictionary.CreateRange<DocumentId, DocumentState>( _projectInfo.Documents.Select(d => new KeyValuePair<DocumentId, DocumentState>(d.Id, CreateDocument(_projectInfo, d, languageServices, solutionServices)))); _documentStates = docStates; var additionalDocStates = ImmutableDictionary.CreateRange<DocumentId, TextDocumentState>( _projectInfo.AdditionalDocuments.Select(d => new KeyValuePair<DocumentId, TextDocumentState>(d.Id, TextDocumentState.Create(d, solutionServices)))); _additionalDocumentStates = additionalDocStates; _lazyLatestDocumentVersion = new AsyncLazy<VersionStamp>(c => ComputeLatestDocumentVersionAsync(docStates, additionalDocStates, c), cacheResult: true); _lazyLatestDocumentTopLevelChangeVersion = new AsyncLazy<VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(docStates, additionalDocStates, c), cacheResult: true); // for now, let it re-calculate if anything changed. // TODO: optimize this so that we only re-calcuate checksums that are actually changed _lazyChecksums = new AsyncLazy<ProjectStateChecksums>(ComputeChecksumsAsync, cacheResult: true); }
private SolutionState( BranchId branchId, int workspaceVersion, SolutionServices solutionServices, SolutionId id, string filePath, IEnumerable<ProjectId> projectIds, ImmutableDictionary<ProjectId, ProjectState> idToProjectStateMap, ImmutableDictionary<ProjectId, CompilationTracker> projectIdToTrackerMap, ImmutableDictionary<string, ImmutableArray<DocumentId>> linkedFilesMap, ProjectDependencyGraph dependencyGraph, VersionStamp version, Lazy<VersionStamp> lazyLatestProjectVersion) { _branchId = branchId; _workspaceVersion = workspaceVersion; _id = id; _filePath = filePath; _solutionServices = solutionServices; _projectIds = projectIds.ToImmutableReadOnlyListOrEmpty(); _projectIdToProjectStateMap = idToProjectStateMap; _projectIdToTrackerMap = projectIdToTrackerMap; _linkedFilesMap = linkedFilesMap; _dependencyGraph = dependencyGraph; _version = version; _lazyLatestProjectVersion = lazyLatestProjectVersion; CheckInvariants(); }
internal ProjectState(ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices) { Contract.ThrowIfNull(projectInfo); Contract.ThrowIfNull(languageServices); Contract.ThrowIfNull(solutionServices); _languageServices = languageServices; _solutionServices = solutionServices; _projectInfo = FixProjectInfo(projectInfo); _documentIds = _projectInfo.Documents.Select(d => d.Id).ToImmutableArray(); _additionalDocumentIds = this.ProjectInfo.AdditionalDocuments.Select(d => d.Id).ToImmutableArray(); var docStates = ImmutableDictionary.CreateRange<DocumentId, DocumentState>( _projectInfo.Documents.Select(d => new KeyValuePair<DocumentId, DocumentState>(d.Id, CreateDocument(this.ProjectInfo, d, languageServices, solutionServices)))); _documentStates = docStates; var additionalDocStates = ImmutableDictionary.CreateRange<DocumentId, TextDocumentState>( _projectInfo.AdditionalDocuments.Select(d => new KeyValuePair<DocumentId, TextDocumentState>(d.Id, TextDocumentState.Create(d, solutionServices)))); _additionalDocumentStates = additionalDocStates; _lazyLatestDocumentVersion = new AsyncLazy<VersionStamp>(c => ComputeLatestDocumentVersionAsync(docStates, additionalDocStates, c), cacheResult: true); _lazyLatestDocumentTopLevelChangeVersion = new AsyncLazy<VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(docStates, additionalDocStates, c), cacheResult: true); }
public static ValueSource<Compilation> CreateValueSource( Compilation compilation, SolutionServices services) { return services.SupportsCachingRecoverableObjects ? new WeakConstantValueSource<Compilation>(compilation) : (ValueSource<Compilation>)new ConstantValueSource<Compilation>(compilation); }
protected TextDocumentState( SolutionServices solutionServices, DocumentInfo info, ValueSource<TextAndVersion> textSource) { this.solutionServices = solutionServices; this.info = info; this.textSource = textSource; }
private static ValueSource<TreeAndVersion> CreateLazyFullyParsedTree( ValueSource<TextAndVersion> newTextSource, ProjectId cacheKey, string filePath, ParseOptions options, HostLanguageServices languageServices, SolutionServices solutionServices, PreservationMode mode = PreservationMode.PreserveValue) { return new AsyncLazy<TreeAndVersion>( c => FullyParseTreeAsync(newTextSource, cacheKey, filePath, options, languageServices, solutionServices, mode, c), cacheResult: true); }
private DocumentState( HostLanguageServices languageServices, SolutionServices solutionServices, DocumentInfo info, ParseOptions options, ValueSource<TextAndVersion> textSource, ValueSource<TreeAndVersion> treeSource) : base(solutionServices, info, textSource) { _languageServices = languageServices; _options = options; _treeSource = treeSource; }
public static TextDocumentState Create(DocumentInfo info, SolutionServices services) { var textSource = info.TextLoader != null ? CreateRecoverableText(info.TextLoader, info.Id, services, reportInvalidDataException: false) : CreateStrongText(TextAndVersion.Create(SourceText.From(string.Empty, Encoding.UTF8), VersionStamp.Default, info.FilePath)); // remove any initial loader so we don't keep source alive info = info.WithTextLoader(null); return new TextDocumentState( solutionServices: services, info: info, textSource: textSource); }
private DocumentState( HostLanguageServices languageServices, SolutionServices solutionServices, DocumentInfo info, ParseOptions options, ValueSource<TextAndVersion> textSource, ValueSource<TreeAndVersion> treeSource) { this.languageServices = languageServices; this.solutionServices = solutionServices; this.info = info; this.options = options; this.textSource = textSource; this.treeSource = treeSource; }
protected TextDocumentState( SolutionServices solutionServices, DocumentInfo info, SourceText sourceTextOpt, ValueSource<TextAndVersion> textAndVersionSource, ValueSource<DocumentStateChecksums> lazyChecksums) { this.solutionServices = solutionServices; this.info = info; this.sourceTextOpt = sourceTextOpt; this.textAndVersionSource = textAndVersionSource; // for now, let it re-calculate if anything changed. // TODO: optimize this so that we only re-calcuate checksums that are actually changed _lazyChecksums = new AsyncLazy<DocumentStateChecksums>(ComputeChecksumsAsync, cacheResult: true); }
private ProjectState( ProjectInfo projectInfo, ILanguageServiceProvider languageServices, SolutionServices solutionServices, ImmutableList<DocumentId> documentIds, ImmutableDictionary<DocumentId, DocumentState> documentStates, AsyncLazy<VersionStamp> lazyLatestDocumentVersion, AsyncLazy<VersionStamp> lazyLatestDocumentTopLevelChangeVersion) { this.projectInfo = projectInfo; this.solutionServices = solutionServices; this.languageServices = languageServices; this.documentIds = documentIds; this.documentStates = documentStates; this.lazyLatestDocumentVersion = lazyLatestDocumentVersion; this.lazyLatestDocumentTopLevelChangeVersion = lazyLatestDocumentTopLevelChangeVersion; }
private ProjectState( ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices, IEnumerable<DocumentId> documentIds, ImmutableDictionary<DocumentId, DocumentState> documentStates, AsyncLazy<VersionStamp> lazyLatestDocumentVersion, AsyncLazy<VersionStamp> lazyLatestDocumentTopLevelChangeVersion) { this.projectInfo = projectInfo; this.solutionServices = solutionServices; this.languageServices = languageServices; this.documentIds = documentIds.ToImmutableReadOnlyListOrEmpty(); this.documentStates = documentStates; this.lazyLatestDocumentVersion = lazyLatestDocumentVersion; this.lazyLatestDocumentTopLevelChangeVersion = lazyLatestDocumentTopLevelChangeVersion; }
private DocumentState( HostLanguageServices languageServices, SolutionServices solutionServices, DocumentInfo info, ParseOptions options, ValueSource<TextAndVersion> textSource, ValueSource<TreeAndVersion> treeSource) : base(solutionServices, info, textSource) { _languageServices = languageServices; _options = options; // If this is document that doesn't support syntax, then don't even bother holding // onto any tree source. It will never be used to get a tree, and can only hurt us // by possibly holding onto data that might cause a slow memory leak. _treeSource = this.SupportsSyntaxTree ? treeSource : ValueSource<TreeAndVersion>.Empty; }
private ProjectState( ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices, IEnumerable <DocumentId> documentIds, IEnumerable <DocumentId> additionalDocumentIds, ImmutableDictionary <DocumentId, DocumentState> documentStates, ImmutableDictionary <DocumentId, TextDocumentState> additionalDocumentStates, AsyncLazy <VersionStamp> lazyLatestDocumentVersion, AsyncLazy <VersionStamp> lazyLatestDocumentTopLevelChangeVersion) { _projectInfo = projectInfo; _solutionServices = solutionServices; _languageServices = languageServices; _documentIds = documentIds.ToImmutableReadOnlyListOrEmpty(); _additionalDocumentIds = additionalDocumentIds.ToImmutableReadOnlyListOrEmpty(); _documentStates = documentStates; _additionalDocumentStates = additionalDocumentStates; _lazyLatestDocumentVersion = lazyLatestDocumentVersion; _lazyLatestDocumentTopLevelChangeVersion = lazyLatestDocumentTopLevelChangeVersion; _lazyChecksums = new AsyncLazy <ProjectStateChecksums>(ComputeChecksumsAsync, cacheResult: true); }
private ProjectState( ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices, IEnumerable<DocumentId> documentIds, IEnumerable<DocumentId> additionalDocumentIds, ImmutableDictionary<DocumentId, DocumentState> documentStates, ImmutableDictionary<DocumentId, TextDocumentState> additionalDocumentStates, AsyncLazy<VersionStamp> lazyLatestDocumentVersion, AsyncLazy<VersionStamp> lazyLatestDocumentTopLevelChangeVersion) { _projectInfo = projectInfo; _solutionServices = solutionServices; _languageServices = languageServices; _documentIds = documentIds.ToImmutableReadOnlyListOrEmpty(); _additionalDocumentIds = additionalDocumentIds.ToImmutableReadOnlyListOrEmpty(); _documentStates = documentStates; _additionalDocumentStates = additionalDocumentStates; _lazyLatestDocumentVersion = lazyLatestDocumentVersion; _lazyLatestDocumentTopLevelChangeVersion = lazyLatestDocumentTopLevelChangeVersion; _lazyChecksums = new AsyncLazy<ProjectStateChecksums>(ComputeChecksumsAsync, cacheResult: true); }
internal ProjectState(ProjectInfo projectInfo, ILanguageServiceProvider languageServiceProvider, SolutionServices solutionServices) { Contract.ThrowIfNull(projectInfo); Contract.ThrowIfNull(languageServiceProvider); Contract.ThrowIfNull(solutionServices); this.languageServices = languageServiceProvider; this.solutionServices = solutionServices; this.projectInfo = FixProjectInfo(projectInfo); this.documentIds = this.projectInfo.Documents.Select(d => d.Id).ToImmutableList(); var docStates = ImmutableDictionary.CreateRange <DocumentId, DocumentState>( this.projectInfo.Documents.Select(d => new KeyValuePair <DocumentId, DocumentState>(d.Id, CreateDocument(this.ProjectInfo, d, languageServiceProvider, solutionServices)))); this.documentStates = docStates; this.lazyLatestDocumentVersion = new AsyncLazy <VersionStamp>(this.ComputeLatestDocumentVersionAsync, cacheResult: true); this.lazyLatestDocumentTopLevelChangeVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(docStates, c), cacheResult: true); }
internal ProjectState(ProjectInfo projectInfo, ILanguageServiceProvider languageServiceProvider, SolutionServices solutionServices) { Contract.ThrowIfNull(projectInfo); Contract.ThrowIfNull(languageServiceProvider); Contract.ThrowIfNull(solutionServices); this.languageServices = languageServiceProvider; this.solutionServices = solutionServices; this.projectInfo = FixProjectInfo(projectInfo); this.documentIds = this.projectInfo.Documents.Select(d => d.Id).ToImmutableList(); var docStates = ImmutableDictionary.CreateRange<DocumentId, DocumentState>( this.projectInfo.Documents.Select(d => new KeyValuePair<DocumentId, DocumentState>(d.Id, CreateDocument(this.ProjectInfo, d, languageServiceProvider, solutionServices)))); this.documentStates = docStates; this.lazyLatestDocumentVersion = new AsyncLazy<VersionStamp>(this.ComputeLatestDocumentVersionAsync, cacheResult: true); this.lazyLatestDocumentTopLevelChangeVersion = new AsyncLazy<VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(docStates, c), cacheResult: true); }
private DocumentState( HostLanguageServices languageServices, SolutionServices solutionServices, IDocumentServiceProvider?documentServiceProvider, DocumentInfo.DocumentAttributes attributes, ParseOptions?options, ValueSource <AnalyzerConfigSet> analyzerConfigSetSource, SourceText?sourceText, ValueSource <TextAndVersion> textSource, ValueSource <TreeAndVersion> treeSource) : base(solutionServices, documentServiceProvider, attributes, sourceText, textSource) { _languageServices = languageServices; _options = options; _analyzerConfigSetSource = analyzerConfigSetSource; // If this is document that doesn't support syntax, then don't even bother holding // onto any tree source. It will never be used to get a tree, and can only hurt us // by possibly holding onto data that might cause a slow memory leak. _treeSource = this.SupportsSyntaxTree ? treeSource : ValueSource <TreeAndVersion> .Empty; }
public ProjectState(ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices) { Contract.ThrowIfNull(projectInfo); Contract.ThrowIfNull(languageServices); Contract.ThrowIfNull(solutionServices); _languageServices = languageServices; _solutionServices = solutionServices; _projectInfo = FixProjectInfo(projectInfo); _documentIds = _projectInfo.Documents.Select(d => d.Id).ToImmutableArray(); _additionalDocumentIds = _projectInfo.AdditionalDocuments.Select(d => d.Id).ToImmutableArray(); var docStates = ImmutableDictionary.CreateRange <DocumentId, DocumentState>( _projectInfo.Documents.Select(d => new KeyValuePair <DocumentId, DocumentState>(d.Id, CreateDocument(_projectInfo, d, languageServices, solutionServices)))); _documentStates = docStates; var additionalDocStates = ImmutableDictionary.CreateRange <DocumentId, TextDocumentState>( _projectInfo.AdditionalDocuments.Select(d => new KeyValuePair <DocumentId, TextDocumentState>(d.Id, TextDocumentState.Create(d, solutionServices)))); _additionalDocumentStates = additionalDocStates; _lazyLatestDocumentVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentVersionAsync(docStates, additionalDocStates, c), cacheResult: true); _lazyLatestDocumentTopLevelChangeVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(docStates, additionalDocStates, c), cacheResult: true); // for now, let it re-calculate if anything changed. // TODO: optimize this so that we only re-calcuate checksums that are actually changed _lazyChecksums = new AsyncLazy <ProjectStateChecksums>(ComputeChecksumsAsync, cacheResult: true); }
// use static method so we don't capture references to this private static Tuple <ValueSource <TextAndVersion>, TreeAndVersion> CreateRecoverableTextAndTree( SyntaxNode newRoot, VersionStamp textVersion, VersionStamp treeVersion, Encoding encoding, DocumentInfo.DocumentAttributes attributes, ParseOptions options, ISyntaxTreeFactoryService factory, PreservationMode mode, SolutionServices solutionServices) { var filePath = attributes.FilePath; SyntaxTree tree = null; ValueSource <TextAndVersion> lazyTextAndVersion = null; if ((mode == PreservationMode.PreserveIdentity) || !factory.CanCreateRecoverableTree(newRoot)) { // its okay to use a strong cached AsyncLazy here because the compiler layer SyntaxTree will also keep the text alive once its built. lazyTextAndVersion = new TreeTextSource( new AsyncLazy <SourceText>( c => tree.GetTextAsync(c), c => tree.GetText(c), cacheResult: true), textVersion, filePath); tree = factory.CreateSyntaxTree(GetSyntaxTreeFilePath(attributes), options, encoding, newRoot); } else { // uses CachedWeakValueSource so the document and tree will return the same SourceText instance across multiple accesses as long // as the text is referenced elsewhere. lazyTextAndVersion = new TreeTextSource( new CachedWeakValueSource <SourceText>( new AsyncLazy <SourceText>( c => BuildRecoverableTreeTextAsync(tree, encoding, c), c => BuildRecoverableTreeText(tree, encoding, c), cacheResult: false)), textVersion, filePath); tree = factory.CreateRecoverableTree(attributes.Id.ProjectId, GetSyntaxTreeFilePath(attributes), options, lazyTextAndVersion, encoding, newRoot); } return(Tuple.Create(lazyTextAndVersion, TreeAndVersion.Create(tree, treeVersion))); }
public ProjectState(ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices) { Contract.ThrowIfNull(projectInfo); Contract.ThrowIfNull(languageServices); Contract.ThrowIfNull(solutionServices); _languageServices = languageServices; _solutionServices = solutionServices; var projectInfoFixed = FixProjectInfo(projectInfo); // We need to compute our AnalyerConfigDocumentStates first, since we use those to produce our DocumentStates AnalyzerConfigDocumentStates = new TextDocumentStates <AnalyzerConfigDocumentState>(projectInfoFixed.AnalyzerConfigDocuments, info => new AnalyzerConfigDocumentState(info, solutionServices)); _lazyAnalyzerConfigSet = ComputeAnalyzerConfigSetValueSource(AnalyzerConfigDocumentStates); // Add analyzer config information to the compilation options if (projectInfoFixed.CompilationOptions != null) { projectInfoFixed = projectInfoFixed.WithCompilationOptions( projectInfoFixed.CompilationOptions.WithSyntaxTreeOptionsProvider( new WorkspaceSyntaxTreeOptionsProvider(_lazyAnalyzerConfigSet))); } var parseOptions = projectInfoFixed.ParseOptions; DocumentStates = new TextDocumentStates <DocumentState>(projectInfoFixed.Documents, info => CreateDocument(info, parseOptions)); AdditionalDocumentStates = new TextDocumentStates <TextDocumentState>(projectInfoFixed.AdditionalDocuments, info => new TextDocumentState(info, solutionServices)); _lazyLatestDocumentVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentVersionAsync(DocumentStates, AdditionalDocumentStates, c), cacheResult: true); _lazyLatestDocumentTopLevelChangeVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(DocumentStates, AdditionalDocumentStates, c), cacheResult: true); // ownership of information on document has moved to project state. clear out documentInfo the state is // holding on. otherwise, these information will be held onto unnecessarily by projectInfo even after // the info has changed by DocumentState. // we hold onto the info so that we don't need to duplicate all information info already has in the state _projectInfo = ClearAllDocumentsFromProjectInfo(projectInfoFixed); _lazyChecksums = new AsyncLazy <ProjectStateChecksums>(ComputeChecksumsAsync, cacheResult: true); }
public static SourceGeneratedDocumentState Create( string hintName, SourceText generatedSourceText, SyntaxTree generatedSyntaxTree, DocumentId documentId, ISourceGenerator sourceGenerator, HostLanguageServices languageServices, SolutionServices solutionServices, CancellationToken cancellationToken ) { var options = generatedSyntaxTree.Options; var filePath = generatedSyntaxTree.FilePath; var textAndVersion = TextAndVersion.Create(generatedSourceText, VersionStamp.Create()); ValueSource <TextAndVersion> textSource = new ConstantValueSource <TextAndVersion>( textAndVersion ); var root = generatedSyntaxTree.GetRoot(cancellationToken); Contract.ThrowIfNull( languageServices.SyntaxTreeFactory, "We should not have a generated syntax tree for a language that doesn't support trees." ); if (languageServices.SyntaxTreeFactory.CanCreateRecoverableTree(root)) { // We will only create recoverable text if we can create a recoverable tree; if we created a // recoverable text but not a new tree, it would mean tree.GetText() could still potentially return // the non-recoverable text, but asking the document directly for it's text would give a recoverable // text with a different object identity. textSource = CreateRecoverableText(textAndVersion, solutionServices); generatedSyntaxTree = languageServices.SyntaxTreeFactory.CreateRecoverableTree( documentId.ProjectId, filePath: generatedSyntaxTree.FilePath, options, textSource, generatedSourceText.Encoding, root ); } var treeAndVersion = TreeAndVersion.Create(generatedSyntaxTree, textAndVersion.Version); return(new SourceGeneratedDocumentState( languageServices, solutionServices, documentServiceProvider: null, new DocumentInfo.DocumentAttributes( documentId, name: hintName, folders: SpecializedCollections.EmptyReadOnlyList <string>(), options.Kind, filePath: filePath, isGenerated: true, designTimeOnly: false ), options, sourceText: null, // don't strongly hold the text textSource, treeAndVersion, sourceGenerator, hintName )); }
protected static ValueSource <TextAndVersion> CreateRecoverableText(TextLoader loader, DocumentId documentId, SolutionServices services, bool reportInvalidDataException) { return(new RecoverableTextAndVersion( new AsyncLazy <TextAndVersion>( asynchronousComputeFunction: c => LoadTextAsync(loader, documentId, services, reportInvalidDataException, c), synchronousComputeFunction: c => LoadTextSynchronously(loader, documentId, services, reportInvalidDataException, c), cacheResult: false), services.TemporaryStorage)); }
private static ValueSource<TextAndVersion> CreateStrongText(TextLoader loader, DocumentId documentId, SolutionServices services) { return new AsyncLazy<TextAndVersion>(c => LoadTextAsync(loader, documentId, services, c), cacheResult: true); }
internal ProjectState(ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices) { Contract.ThrowIfNull(projectInfo); Contract.ThrowIfNull(languageServices); Contract.ThrowIfNull(solutionServices); _languageServices = languageServices; _solutionServices = solutionServices; _projectInfo = FixProjectInfo(projectInfo); _documentIds = _projectInfo.Documents.Select(d => d.Id).ToImmutableArray(); _additionalDocumentIds = this.ProjectInfo.AdditionalDocuments.Select(d => d.Id).ToImmutableArray(); var docStates = ImmutableDictionary.CreateRange <DocumentId, DocumentState>( _projectInfo.Documents.Select(d => new KeyValuePair <DocumentId, DocumentState>(d.Id, CreateDocument(this.ProjectInfo, d, languageServices, solutionServices)))); _documentStates = docStates; var additionalDocStates = ImmutableDictionary.CreateRange <DocumentId, TextDocumentState>( _projectInfo.AdditionalDocuments.Select(d => new KeyValuePair <DocumentId, TextDocumentState>(d.Id, TextDocumentState.Create(d, solutionServices)))); _additionalDocumentStates = additionalDocStates; _lazyLatestDocumentVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentVersionAsync(docStates, additionalDocStates, c), cacheResult: true); _lazyLatestDocumentTopLevelChangeVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(docStates, additionalDocStates, c), cacheResult: true); }
// use static method so we don't capture references to this private static Tuple<AsyncLazy<TextAndVersion>, TreeAndVersion> CreateRecoverableTextAndTree( SyntaxNode newRoot, VersionStamp textVersion, VersionStamp treeVersion, DocumentInfo info, ParseOptions options, ISyntaxTreeFactoryService factory, PreservationMode mode, SolutionServices solutionServices) { string filePath = info.FilePath; TreeAndVersion lazyTree = null; // Since this text will be created from a tree, it doesn't have an explicit encoding. // We'll check for this case when writing out the file, and look at the original file's // encoding. Encoding encoding = null; // this captures the lazyTree local var lazyText = new AsyncLazy<TextAndVersion>( c => GetTextAndVersionAsync(lazyTree, textVersion, encoding, filePath, c), c => GetTextAndVersion(lazyTree, textVersion, encoding, filePath, c), cacheResult: false); lazyTree = TreeAndVersion.Create( (mode == PreservationMode.PreserveIdentity) || !solutionServices.SupportsCachingRecoverableObjects ? factory.CreateSyntaxTree(GetSyntaxTreeFilePath(info), options, newRoot, encoding) : factory.CreateRecoverableTree(info.Id.ProjectId, GetSyntaxTreeFilePath(info), options, lazyText, newRoot), treeVersion); return Tuple.Create(lazyText, lazyTree); }
private static async Task <TextAndVersion> LoadTextAsync(TextLoader loader, DocumentId documentId, SolutionServices services, CancellationToken cancellationToken) { try { using (ExceptionHelpers.SuppressFailFast()) { var result = await loader.LoadTextAndVersionAsync(services.Workspace, documentId, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); return(result); } } catch (OperationCanceledException) { // if load text is failed due to a cancellation, make sure we propagate it out to the caller throw; } catch (Exception e) { services.Workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.FileAccessFailure, e.Message, documentId)); return(TextAndVersion.Create(SourceText.From(string.Empty), VersionStamp.Default, documentId.DebuggerText)); } }
private static async Task<TreeAndVersion> FullyParseTreeAsync( ValueSource<TextAndVersion> newTextSource, ProjectId cacheKey, string filePath, ParseOptions options, HostLanguageServices languageServices, SolutionServices solutionServices, PreservationMode mode, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Workspace_Document_State_FullyParseSyntaxTree, cancellationToken)) { var textAndVersion = await newTextSource.GetValueAsync(cancellationToken).ConfigureAwait(false); var text = textAndVersion.Text; var treeFactory = languageServices.GetService<ISyntaxTreeFactoryService>(); var tree = treeFactory.ParseSyntaxTree(filePath, options, text, cancellationToken); if (mode == PreservationMode.PreserveValue && solutionServices.SupportsCachingRecoverableObjects) { var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false); tree = treeFactory.CreateRecoverableTree(cacheKey, tree.FilePath, tree.Options, newTextSource, root); } Contract.ThrowIfNull(tree); // text version for this document should be unique. use it as a starting point. return TreeAndVersion.Create(tree, textAndVersion.Version); } }
protected static ValueSource <TextAndVersion> CreateRecoverableText(TextAndVersion text, SolutionServices services) { var result = new RecoverableTextAndVersion(CreateStrongText(text), services.TemporaryStorage); // This RecoverableTextAndVersion is created directly from a TextAndVersion instance. In its initial state, // the RecoverableTextAndVersion keeps a strong reference to the initial TextAndVersion, and only // transitions to a weak reference backed by temporary storage after the first time GetValue (or // GetValueAsync) is called. Since we know we are creating a RecoverableTextAndVersion for the purpose of // avoiding problematic address space overhead, we call GetValue immediately to force the object to weakly // hold its data from the start. result.GetValue(); return(result); }
protected static ValueSource<TextAndVersion> CreateRecoverableText(TextLoader loader, DocumentId documentId, SolutionServices services, bool reportInvalidDataException) { return new RecoverableTextAndVersion( new AsyncLazy<TextAndVersion>( asynchronousComputeFunction: c => LoadTextAsync(loader, documentId, services, reportInvalidDataException, c), synchronousComputeFunction: c => LoadTextSynchronously(loader, documentId, services, reportInvalidDataException, c), cacheResult: false), services.TemporaryStorage); }
private static ValueSource <TextAndVersion> CreateRecoverableText(TextLoader loader, DocumentId documentId, SolutionServices services) { return(new RecoverableTextAndVersion( new AsyncLazy <TextAndVersion>(c => LoadTextAsync(loader, documentId, services, c), cacheResult: false), services.TemporaryStorage, services.TextCache)); }
protected static ValueSource <TextAndVersion> CreateStrongText(TextLoader loader, DocumentId documentId, SolutionServices services) { return(new AsyncLazy <TextAndVersion>( asynchronousComputeFunction: cancellationToken => loader.LoadTextAsync(services.Workspace, documentId, cancellationToken), synchronousComputeFunction: cancellationToken => loader.LoadTextSynchronously(services.Workspace, documentId, cancellationToken), cacheResult: true)); }
protected static async Task<TextAndVersion> LoadTextAsync(TextLoader loader, DocumentId documentId, SolutionServices services, bool reportInvalidDataException, CancellationToken cancellationToken) { int retries = 0; while (true) { try { using (ExceptionHelpers.SuppressFailFast()) { var result = await loader.LoadTextAndVersionAsync(services.Workspace, documentId, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); return result; } } catch (OperationCanceledException) { // if load text is failed due to a cancellation, make sure we propagate it out to the caller throw; } catch (IOException e) { if (++retries > MaxRetries) { services.Workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, e.Message, documentId)); return TextAndVersion.Create(SourceText.From(string.Empty, Encoding.UTF8), VersionStamp.Default, documentId.GetDebuggerDisplay()); } // fall out to try again } catch (InvalidDataException e) { // TODO: Adjust this behavior in the future if we add support for non-text additional files if (reportInvalidDataException) { services.Workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, e.Message, documentId)); } return TextAndVersion.Create(SourceText.From(string.Empty, Encoding.UTF8), VersionStamp.Default, documentId.GetDebuggerDisplay()); } // try again after a delay await Task.Delay(RetryDelay).ConfigureAwait(false); } }
// use static method so we don't capture references to this private static Tuple <AsyncLazy <TextAndVersion>, TreeAndVersion> CreateRecoverableTextAndTree( SyntaxNode newRoot, VersionStamp textVersion, VersionStamp treeVersion, DocumentInfo info, ParseOptions options, ISyntaxTreeFactoryService factory, PreservationMode mode, SolutionServices solutionServices) { string filePath = info.FilePath; TreeAndVersion lazyTree = null; // Since this text will be created from a tree, it doesn't have an explicit encoding. // We'll check for this case when writing out the file, and look at the original file's // encoding. Encoding encoding = null; // this captures the lazyTree local var lazyText = new AsyncLazy <TextAndVersion>( c => GetTextAndVersionAsync(lazyTree, textVersion, encoding, filePath, c), c => GetTextAndVersion(lazyTree, textVersion, encoding, filePath, c), cacheResult: false); lazyTree = TreeAndVersion.Create( (mode == PreservationMode.PreserveIdentity) || !solutionServices.SupportsCachingRecoverableObjects ? factory.CreateSyntaxTree(GetSyntaxTreeFilePath(info), options, newRoot, encoding) : factory.CreateRecoverableTree(info.Id.ProjectId, GetSyntaxTreeFilePath(info), options, lazyText, newRoot), treeVersion); return(Tuple.Create(lazyText, lazyTree)); }
private SolutionState CreatePrimarySolution( BranchId branchId, int workspaceVersion, SolutionServices services) { if (branchId == _branchId && workspaceVersion == _workspaceVersion && services == _solutionServices) { return this; } return new SolutionState( branchId, workspaceVersion, services, _id, _filePath, _projectIds, _projectIdToProjectStateMap, _projectIdToTrackerMap, _linkedFilesMap, _dependencyGraph, _version, _lazyLatestProjectVersion); }
protected static ValueSource <TextAndVersion> CreateStrongText(TextLoader loader, DocumentId documentId, SolutionServices services, bool reportInvalidDataException) { return(new AsyncLazy <TextAndVersion>(c => LoadTextAsync(loader, documentId, services, reportInvalidDataException, c), cacheResult: true)); }
protected static ValueSource <TextAndVersion> CreateRecoverableText(TextAndVersion text, SolutionServices services) { return(new RecoverableTextAndVersion(CreateStrongText(text), services.TemporaryStorage)); }
protected static async Task <TextAndVersion> LoadTextAsync(TextLoader loader, DocumentId documentId, SolutionServices services, bool reportInvalidDataException, CancellationToken cancellationToken) { try { using (ExceptionHelpers.SuppressFailFast()) { var result = await loader.LoadTextAndVersionAsync(services.Workspace, documentId, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); return(result); } } catch (OperationCanceledException) { // if load text is failed due to a cancellation, make sure we propagate it out to the caller throw; } catch (IOException e) { services.Workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, e.Message, documentId)); return(TextAndVersion.Create(SourceText.From(string.Empty, Encoding.UTF8), VersionStamp.Default, documentId.GetDebuggerDisplay())); } catch (InvalidDataException e) { // TODO: Adjust this behavior in the future if we add support for non-text additional files if (reportInvalidDataException) { services.Workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, e.Message, documentId)); } return(TextAndVersion.Create(SourceText.From(string.Empty, Encoding.UTF8), VersionStamp.Default, documentId.GetDebuggerDisplay())); } }
protected static TextAndVersion LoadTextSynchronously(TextLoader loader, DocumentId documentId, SolutionServices services, bool reportInvalidDataException, CancellationToken cancellationToken) { int retries = 0; while (true) { try { return(loader.LoadTextAndVersionSynchronously(services.Workspace, documentId, cancellationToken)); } catch (OperationCanceledException) { // if load text is failed due to a cancellation, make sure we propagate it out to the caller throw; } catch (IOException e) { if (++retries > MaxRetries) { services.Workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, e.Message, documentId)); return(TextAndVersion.Create(SourceText.From(string.Empty, Encoding.UTF8), VersionStamp.Default, documentId.GetDebuggerDisplay())); } // fall out to try again } catch (InvalidDataException e) { // TODO: Adjust this behavior in the future if we add support for non-text additional files if (reportInvalidDataException) { services.Workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, e.Message, documentId)); } return(TextAndVersion.Create(SourceText.From(string.Empty, Encoding.UTF8), VersionStamp.Default, documentId.GetDebuggerDisplay())); } // try again after a delay Thread.Sleep(RetryDelay); } }
// use static method so we don't capture references to this private static Tuple <AsyncLazy <TextAndVersion>, TreeAndVersion> CreateRecoverableTextAndTree( SyntaxNode newRoot, VersionStamp textVersion, VersionStamp treeVersion, Encoding encoding, DocumentInfo info, ParseOptions options, ISyntaxTreeFactoryService factory, PreservationMode mode, SolutionServices solutionServices) { string filePath = info.FilePath; TreeAndVersion lazyTree = null; // this captures the lazyTree local var lazyText = new AsyncLazy <TextAndVersion>( c => GetTextAndVersionAsync(lazyTree, textVersion, encoding, filePath, c), c => GetTextAndVersion(lazyTree, textVersion, encoding, filePath, c), cacheResult: false); lazyTree = TreeAndVersion.Create( (mode == PreservationMode.PreserveIdentity) || !solutionServices.SupportsCachingRecoverableObjects ? factory.CreateSyntaxTree(GetSyntaxTreeFilePath(info), options, encoding, newRoot) : factory.CreateRecoverableTree(info.Id.ProjectId, GetSyntaxTreeFilePath(info), options, lazyText, encoding, newRoot), treeVersion); return(Tuple.Create(lazyText, lazyTree)); }
public ProjectState(ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices) { Contract.ThrowIfNull(projectInfo); Contract.ThrowIfNull(languageServices); Contract.ThrowIfNull(solutionServices); _languageServices = languageServices; _solutionServices = solutionServices; var projectInfoFixed = FixProjectInfo(projectInfo); // We need to compute our AnalyerConfigDocumentStates first, since we use those to produce our DocumentStates _analyzerConfigDocumentStates = ImmutableSortedDictionary.CreateRange(DocumentIdComparer.Instance, projectInfoFixed.AnalyzerConfigDocuments.Select(d => KeyValuePairUtil.Create(d.Id, new AnalyzerConfigDocumentState(d, solutionServices)))); _lazyAnalyzerConfigSet = ComputeAnalyzerConfigSetValueSource(_analyzerConfigDocumentStates.Values); _documentIds = projectInfoFixed.Documents.Select(d => d.Id).ToImmutableList(); _additionalDocumentIds = projectInfoFixed.AdditionalDocuments.Select(d => d.Id).ToImmutableList(); var parseOptions = projectInfoFixed.ParseOptions; var docStates = ImmutableSortedDictionary.CreateRange(DocumentIdComparer.Instance, projectInfoFixed.Documents.Select(d => new KeyValuePair <DocumentId, DocumentState>(d.Id, CreateDocument(d, parseOptions)))); _documentStates = docStates; var additionalDocStates = ImmutableSortedDictionary.CreateRange(DocumentIdComparer.Instance, projectInfoFixed.AdditionalDocuments.Select(d => new KeyValuePair <DocumentId, TextDocumentState>(d.Id, new TextDocumentState(d, solutionServices)))); _additionalDocumentStates = additionalDocStates; _lazyLatestDocumentVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentVersionAsync(docStates, additionalDocStates, c), cacheResult: true); _lazyLatestDocumentTopLevelChangeVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(docStates, additionalDocStates, c), cacheResult: true); // ownership of information on document has moved to project state. clear out documentInfo the state is // holding on. otherwise, these information will be held onto unnecessarily by projectInfo even after // the info has changed by DocumentState. // we hold onto the info so that we don't need to duplicate all information info already has in the state _projectInfo = ClearAllDocumentsFromProjectInfo(projectInfoFixed); _lazyChecksums = new AsyncLazy <ProjectStateChecksums>(ComputeChecksumsAsync, cacheResult: true); }
public ProjectState(ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices) { Contract.ThrowIfNull(projectInfo); Contract.ThrowIfNull(languageServices); Contract.ThrowIfNull(solutionServices); _languageServices = languageServices; _solutionServices = solutionServices; var projectInfoFixed = FixProjectInfo(projectInfo); _documentIds = projectInfoFixed.Documents.Select(d => d.Id).ToImmutableArray(); _additionalDocumentIds = projectInfoFixed.AdditionalDocuments.Select(d => d.Id).ToImmutableArray(); var parseOptions = projectInfoFixed.ParseOptions; var docStates = ImmutableDictionary.CreateRange <DocumentId, DocumentState>( projectInfoFixed.Documents.Select(d => new KeyValuePair <DocumentId, DocumentState>(d.Id, CreateDocument(d, parseOptions, languageServices, solutionServices)))); _documentStates = docStates; var additionalDocStates = ImmutableDictionary.CreateRange <DocumentId, TextDocumentState>( projectInfoFixed.AdditionalDocuments.Select(d => new KeyValuePair <DocumentId, TextDocumentState>(d.Id, TextDocumentState.Create(d, solutionServices)))); _additionalDocumentStates = additionalDocStates; _lazyLatestDocumentVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentVersionAsync(docStates, additionalDocStates, c), cacheResult: true); _lazyLatestDocumentTopLevelChangeVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(docStates, additionalDocStates, c), cacheResult: true); // ownership of information on document has moved to project state. clear out documentInfo the state is // holding on. otherwise, these information will be held onto unnecesarily by projectInfo even after // the info has changed by DocumentState. // we hold onto the info so that we don't need to duplicate all information info already has in the state _projectInfo = ClearAllDocumentsFromProjectInfo(projectInfoFixed); _lazyChecksums = new AsyncLazy <ProjectStateChecksums>(ComputeChecksumsAsync, cacheResult: true); }
private static DocumentState CreateDocument(ProjectInfo projectInfo, DocumentInfo documentInfo, HostLanguageServices languageServices, SolutionServices solutionServices) { var doc = DocumentState.Create(documentInfo, projectInfo.ParseOptions, languageServices, solutionServices); if (doc.SourceCodeKind != documentInfo.SourceCodeKind) { doc = doc.UpdateSourceCodeKind(documentInfo.SourceCodeKind); } return(doc); }
protected static ValueSource<TextAndVersion> CreateStrongText(TextLoader loader, DocumentId documentId, SolutionServices services, bool reportInvalidDataException) { return new AsyncLazy<TextAndVersion>(c => LoadTextAsync(loader, documentId, services, reportInvalidDataException, c), cacheResult: true); }
private static DocumentState CreateDocument(ProjectInfo projectInfo, DocumentInfo documentInfo, ILanguageServiceProvider languageServices, SolutionServices solutionServices) { var doc = DocumentState.Create(documentInfo, projectInfo.ParseOptions, languageServices, solutionServices); if (doc.SourceCodeKind != documentInfo.SourceCodeKind) { doc = doc.UpdateSourceCodeKind(documentInfo.SourceCodeKind); } return doc; }
protected static ValueSource<TextAndVersion> CreateRecoverableText(TextAndVersion text, SolutionServices services) { return new RecoverableTextAndVersion(CreateStrongText(text), services.TemporaryStorage); }
private static async Task<TextAndVersion> LoadTextAsync(TextLoader loader, DocumentId documentId, SolutionServices services, CancellationToken cancellationToken) { try { using (ExceptionHelpers.SuppressFailFast()) { var result = await loader.LoadTextAndVersionAsync(services.Workspace, documentId, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); return result; } } catch (OperationCanceledException) { // if load text is failed due to a cancellation, make sure we propagate it out to the caller throw; } catch (IOException e) { services.Workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, e.Message, documentId)); return TextAndVersion.Create(SourceText.From(string.Empty, Encoding.UTF8), VersionStamp.Default, documentId.GetDebuggerDisplay()); } }
private static ValueSource <TextAndVersion> CreateStrongText(TextLoader loader, DocumentId documentId, SolutionServices services) { return(new AsyncLazy <TextAndVersion>(c => LoadTextAsync(loader, documentId, services, c), cacheResult: true)); }