예제 #1
0
        public void UpdateCode(string contentId, TextDiff update, bool highlight)
        {
            Task.Run(() =>
            {
                // updates needs to be processed in the same order they are generated
                // this method might wait for the next update, thus running in background
                // thread
                Content content;
                var dict = _contentDictionary;
                lock (dict)
                {
                    while (update.Update != Volatile.Read(ref _nextUpdate))
                    {
                        Monitor.Wait(dict);
                    }

                    Interlocked.Increment(ref _nextUpdate);

                    if (!_contentDictionary.TryGetValue(contentId, out content))
                    {
                        throw new Exception("Content wasn't in dictionary. Illegal code::update sent");
                    }

                    if (update.Start == 0 && update.Added == content.ContentString.Length && update.Text == content.ContentString)
                    {
                        goto highlight; // editor sends updates when files are opened
                    }
                    var text = content.ContentString;
                    var sb   = new StringBuilder().Append(text, 0, update.Start);
                    sb.Append(update.Text);
                    sb.Append(text, update.Start + update.Removed, text.Length - update.Start - update.Removed);
                    text        = sb.ToString();
                    Content old = content;
                    content     = content.WithText(text);

                    if (!_contentDictionary.TryUpdate(contentId, content, old))
                    {
                        throw new Exception("Content has been updated by other method. State inconclusive.");
                    }
                }

                // mark dirty
                MarkTab(contentId, dirty: true);

                var workspace = _state.Workspace;
                if (workspace == null)
                {
                    return;
                }

                var proj = workspace.Projects.SingleOrDefault(p => content.RelativePath.StartsWith(p.RelativePath, StringComparison.OrdinalIgnoreCase));
                if (proj == null)
                {
                    return;
                }

                _compilations.AddOrUpdate(proj.Id, id => ProjectCompilation.Create(proj.Name, proj.Id), (i, p) => p.InvalidateSources());

                highlight:
                if (highlight)
                {
                    Highlight(content);
                }
            });
        }
예제 #2
0
 public void UpdateCode(string contentId, TextDiff update)
 {
     UpdateCode(contentId, update, true);
 }