예제 #1
0
        protected TextDocumentState(
            SolutionServices solutionServices,
            IDocumentServiceProvider?documentServiceProvider,
            DocumentInfo.DocumentAttributes attributes,
            SourceText?sourceText,
            ValueSource <TextAndVersion> textAndVersionSource
            )
        {
            this.solutionServices     = solutionServices;
            this.sourceText           = sourceText;
            this.TextAndVersionSource = textAndVersionSource;

            Attributes = attributes;
            Services   = documentServiceProvider ?? DefaultTextDocumentServiceProvider.Instance;

            // This constructor is called whenever we're creating a new TextDocumentState from another
            // TextDocumentState, and so we populate all the fields from the inputs. We will always create
            // a new AsyncLazy to compute the checksum though, and that's because there's no practical way for
            // the newly created TextDocumentState to have the same checksum as a previous TextDocumentState:
            // if we're creating a new state, it's because something changed, and we'll have to create a new checksum.
            _lazyChecksums = new AsyncLazy <DocumentStateChecksums>(
                ComputeChecksumsAsync,
                cacheResult: true
                );
        }
예제 #2
0
 private SourceGeneratedDocumentState(
     HostLanguageServices languageServices,
     SolutionServices solutionServices,
     IDocumentServiceProvider?documentServiceProvider,
     DocumentInfo.DocumentAttributes attributes,
     ParseOptions?options,
     SourceText?sourceText,
     ValueSource <TextAndVersion> textSource,
     TreeAndVersion treeAndVersion,
     ISourceGenerator sourceGenerator,
     string hintName
     )
     : base(
         languageServices,
         solutionServices,
         documentServiceProvider,
         attributes,
         options,
         sourceText,
         textSource,
         new ConstantValueSource <TreeAndVersion>(treeAndVersion)
         )
 {
     SourceGenerator = sourceGenerator;
     HintName        = hintName;
 }
예제 #3
0
 // This is the string used to represent the FilePath property on a SyntaxTree object.
 // if the document does not yet have a file path, use the document's name instead in regular code
 // or an empty string in script code.
 private static string GetSyntaxTreeFilePath(DocumentInfo.DocumentAttributes info)
 {
     if (info.FilePath != null)
     {
         return(info.FilePath);
     }
     return(info.SourceCodeKind == SourceCodeKind.Regular
         ? info.Name
         : "");
 }
예제 #4
0
 private AnalyzerConfigDocumentState(
     SolutionServices solutionServices,
     IDocumentServiceProvider documentServiceProvider,
     DocumentInfo.DocumentAttributes attributes,
     SourceText sourceTextOpt,
     ValueSource <TextAndVersion> textAndVersionSource)
     : base(solutionServices, documentServiceProvider, attributes, sourceTextOpt, textAndVersionSource)
 {
     _analyzerConfigValueSource = CreateAnalyzerConfigValueSource();
 }
 private AdditionalDocumentState(
     SolutionServices solutionServices,
     IDocumentServiceProvider documentServiceProvider,
     DocumentInfo.DocumentAttributes attributes,
     SourceText?sourceText,
     ValueSource <TextAndVersion> textAndVersionSource)
     : base(solutionServices, documentServiceProvider, attributes, sourceText, textAndVersionSource)
 {
     _additionalText = new AdditionalTextWithState(this);
 }
예제 #6
0
        private static (ValueSource <TextAndVersion>, TreeAndVersion) CreateRecoverableTextAndTree(
            SyntaxNode newRoot,
            string filePath,
            VersionStamp textVersion,
            VersionStamp treeVersion,
            Encoding?encoding,
            DocumentInfo.DocumentAttributes attributes,
            ParseOptions options,
            ImmutableDictionary <string, ReportDiagnostic>?treeDiagnosticReportingOptions,
            ISyntaxTreeFactoryService factory,
            PreservationMode mode)
        {
            SyntaxTree tree;
            ValueSource <TextAndVersion> lazyTextAndVersion;

            if (mode == PreservationMode.PreserveIdentity || !factory.CanCreateRecoverableTree(newRoot))
            {
                tree = factory.CreateSyntaxTree(filePath, options, encoding, newRoot, treeDiagnosticReportingOptions);

                // 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);
            }
            else
            {
                // There is a strange circularity here: the creation of lazyTextAndVersion reads this local, but will see it as non-null since it
                // only uses it through a lambda that won't have ran. The assignment exists to placate the definite-assignment analysis (which is
                // right to be suspicious of this).
                tree = null !;

                // 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>(
                            // Build text from root, so recoverable tree won't cycle.
                            async cancellationToken => (await tree.GetRootAsync(cancellationToken).ConfigureAwait(false)).GetText(encoding),
                            cancellationToken => tree.GetRoot(cancellationToken).GetText(encoding),
                            cacheResult: false)),
                    textVersion,
                    filePath);

                tree = factory.CreateRecoverableTree(attributes.Id.ProjectId, filePath, options, lazyTextAndVersion, encoding, newRoot, treeDiagnosticReportingOptions);
            }

            return(lazyTextAndVersion, TreeAndVersion.Create(tree, treeVersion));
        }
 private SourceGeneratedDocumentState(
     SourceGeneratedDocumentIdentity documentIdentity,
     HostLanguageServices languageServices,
     SolutionServices solutionServices,
     IDocumentServiceProvider?documentServiceProvider,
     DocumentInfo.DocumentAttributes attributes,
     ParseOptions options,
     ValueSource <TextAndVersion> textSource,
     ValueSource <TreeAndVersion> treeSource)
     : base(languageServices, solutionServices, documentServiceProvider, attributes, options, sourceText: null, textSource, treeSource)
 {
     Identity = documentIdentity;
 }
예제 #8
0
        private DocumentState UpdateAttributes(DocumentInfo.DocumentAttributes attributes)
        {
            Debug.Assert(attributes != Attributes);

            return(new DocumentState(
                       _languageServices,
                       solutionServices,
                       Services,
                       attributes,
                       _options,
                       sourceText,
                       TextAndVersionSource,
                       _treeSource));
        }
예제 #9
0
 private DocumentState(
     HostLanguageServices languageServices,
     SolutionServices solutionServices,
     IDocumentServiceProvider?documentServiceProvider,
     DocumentInfo.DocumentAttributes attributes,
     ParseOptions?options,
     SourceText?sourceText,
     ValueSource <TextAndVersion> textSource,
     ValueSource <TreeAndVersion>?treeSource)
     : base(solutionServices, documentServiceProvider, attributes, sourceText, textSource)
 {
     _languageServices = languageServices;
     _options          = options;
     _treeSource       = treeSource;
 }
예제 #10
0
        protected TextDocumentState(
            SolutionServices solutionServices,
            DocumentInfo.DocumentAttributes attributes,
            SourceText sourceTextOpt,
            ValueSource <TextAndVersion> textAndVersionSource,
            ValueSource <DocumentStateChecksums> lazyChecksums)
        {
            this.solutionServices     = solutionServices;
            this.attributes           = attributes;
            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);
        }
예제 #11
0
        // use static method so we don't capture references to this
        private static Tuple <ValueSource <TextAndVersion>, TreeAndVersion> CreateRecoverableTextAndTree(
            SyntaxNode newRoot,
            string filePath,
            VersionStamp textVersion,
            VersionStamp treeVersion,
            Encoding encoding,
            DocumentInfo.DocumentAttributes attributes,
            ParseOptions options,
            ImmutableDictionary <string, ReportDiagnostic> treeDiagnosticReportingOptionsOpt,
            ISyntaxTreeFactoryService factory,
            PreservationMode mode)
        {
            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(filePath, options, encoding, newRoot, treeDiagnosticReportingOptionsOpt);
            }
            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, filePath, options, lazyTextAndVersion, encoding, newRoot, treeDiagnosticReportingOptionsOpt);
            }

            return(Tuple.Create(lazyTextAndVersion, TreeAndVersion.Create(tree, treeVersion)));
        }
예제 #12
0
        private DocumentState(
            HostLanguageServices languageServices,
            SolutionServices solutionServices,
            DocumentInfo.DocumentAttributes attributes,
            ParseOptions options,
            SourceText sourceTextOpt,
            ValueSource <TextAndVersion> textSource,
            ValueSource <TreeAndVersion> treeSource,
            ValueSource <DocumentStateChecksums> lazyChecksums)
            : base(solutionServices, attributes, sourceTextOpt, textSource, lazyChecksums)
        {
            _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;
        }
예제 #13
0
        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;
        }