예제 #1
0
        private void AddImportTags(ISmartTagSession session, IList<SmartTagActionSet> smartTagActionSets) {
            var textBuffer = _textBuffer;
            var span = session.CreateTrackingSpan(textBuffer);
            var imports = textBuffer.CurrentSnapshot.GetMissingImports(_serviceProvider, span);

            if (imports == MissingImportAnalysis.Empty) {
                return;
            }

            SmartTagController controller;
            session.Properties.TryGetProperty<SmartTagController>(typeof(SmartTagController), out controller);
            if (controller == null) {
                return;
            }

            var task = Volatile.Read(ref controller._curTask);
            var origTask = task;

            var snapshot = textBuffer.CurrentSnapshot;
            if (task != null &&
                task.ApplicableToSpan.GetSpan(snapshot) != imports.ApplicableToSpan.GetSpan(snapshot)) {
                // Previous task is invalid, so abort it and we'll start a
                // new one.
                task.Abort();
                session.Properties.RemoveProperty(typeof(SmartTagAugmentTask));
                task = null;
            }
                
            if (task == null) {
                task = new SmartTagAugmentTask(
                    _serviceProvider,
                    textBuffer,
                    session.TextView,
                    imports
                );
                if (Interlocked.CompareExchange(ref controller._curTask, task, origTask) != origTask) {
                    // Item has been changed by someone else, so abort
                    // Except we should always be on the UI thread here, so
                    // there should be no races.
                    Debug.Fail("Race in AugmentSmartTagSession");
                    return;
                }
            }
                
            session.ApplicableToSpan = imports.ApplicableToSpan;

            var result = task.GetResultIfComplete();
            if (result != null && Interlocked.CompareExchange(ref controller._curTask, null, task) == task) {
                // Provide results if we were the current task and we are
                // now complete
                smartTagActionSets.Add(result);
            }
        }