protected override Task <MSBuildParseResult> StartParseAsync(
            ITextSnapshot2 snapshot, MSBuildParseResult previousParse,
            ITextSnapshot2 previousSnapshot, CancellationToken token)
        {
            if (runtimeInformation == null)
            {
                EnsureInitialized();
            }

            return(Task.Run(() => {
                var oldDoc = previousParse?.MSBuildDocument;

                var filepath = TryGetFilePath();

                MSBuildRootDocument doc = MSBuildRootDocument.Empty;
                try {
                    doc = MSBuildRootDocument.Parse(snapshot.GetTextSource(filepath), oldDoc, schemaProvider, runtimeInformation, taskMetadataBuilder, token);
                } catch (Exception ex) {
                    LoggingService.LogError("Unhandled error in MSBuild parser", ex);
                    doc = MSBuildRootDocument.Empty;
                }

                return new MSBuildParseResult(doc, doc.XDocument, doc.Errors);
            }));
        }
        ParseOperation CreateParseOperation(ITextSnapshot2 snapshot)
        {
            var tokenSource = new CancellationTokenSource();
            var task        = StartParseAsync(snapshot, tokenSource.Token);
            var operation   = new ParseOperation(this, task, snapshot, tokenSource);

                        #pragma warning disable VSTHRD110, VSTHRD105 // Observe result of async calls, Avoid method overloads that assume TaskScheduler.Current

            //capture successful parses
            task.ContinueWith((t, state) => {
                var op = ((ParseOperation)state);
                op.Parser.lastSuccessfulOperation = op;
                try {
                    op.Parser.OnParseCompleted(op.Result, op.Snapshot);
                } catch (Exception ex) {
                    op.Parser.OnUnhandledParseError(ex);
                }
            }, operation, TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously);

            //handle errors
            task.ContinueWith((t, state) => {
                var op = ((ParseOperation)state);
                op.Parser.HandleUnhandledParseError(t.Exception);
            }, operation, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);

                        #pragma warning restore VSTHRD110, VSTHRD105

            return(operation);
        }
 public ParseOperation(BackgroundParser <T> parser, Task <T> operation, ITextSnapshot2 snapshot, CancellationTokenSource tokenSource)
 {
     Parser               = parser;
     Task                 = operation;
     Snapshot             = snapshot;
     this.tokenSource     = tokenSource;
     ownerCount           = 1;
     primaryOwnerCanceled = 0;
 }
        Task <T> StartParseAsync(ITextSnapshot2 snapshot, CancellationToken token)
        {
            var lastSuccessful = lastSuccessfulOperation;

            if (lastSuccessful != null && lastSuccessful.Snapshot.Version.VersionNumber < snapshot.Version.VersionNumber)
            {
                return(StartParseAsync(snapshot, lastSuccessful.Result, lastSuccessful.Snapshot, token));
            }
            return(StartParseAsync(snapshot, default(T), null, token));
        }
        /// <summary>
        /// Get an existing completed or running parse task for the provided snapshot if available, or creates a new parse task.
        /// </summary>
        public Task <T> GetOrParseAsync(ITextSnapshot2 snapshot, CancellationToken token)
        {
            var current = currentOperation;

            if (current != null && current.Snapshot == snapshot && current.RegisterAdditionalCancellationOwner(token))
            {
                return(current.Task);
            }

            currentOperation = current = CreateParseOperation(snapshot);
            return(current.Task);
        }
 public ParseCompletedEventArgs(T parseResult, ITextSnapshot2 snapshot)
 {
     ParseResult = parseResult;
     Snapshot    = snapshot;
 }
 protected abstract Task <T> StartParseAsync(ITextSnapshot2 snapshot, T previousParse, ITextSnapshot2 previousSnapshot, CancellationToken token);
 protected virtual void OnParseCompleted(T parseResult, ITextSnapshot2 snapshot)
 {
     ParseCompleted?.Invoke(this, new ParseCompletedEventArgs <T> (parseResult, snapshot));
 }