Пример #1
0
 void Editor_EndAtomicUndoOperation(object sender, EventArgs e)
 {
     if (beginVersion.CompareAge(Editor.Version) != 0)
     {
         RemoveWidget();
     }
 }
        public HighlightedLine HighlightLine(int lineNumber)
        {
            IDocumentLine documentLine = document.GetLineByNumber(lineNumber);

            if (hasCrashed)
            {
                // don't highlight anymore after we've crashed
                return(new HighlightedLine(document, documentLine));
            }
            ITextSourceVersion newVersion = document.Version;
            CachedLine         cachedLine = null;

            if (cachedLines != null)
            {
                for (int i = 0; i < cachedLines.Count; i++)
                {
                    if (cachedLines[i].DocumentLine == documentLine)
                    {
                        if (newVersion == null || !newVersion.BelongsToSameDocumentAs(cachedLines[i].OldVersion))
                        {
                            // cannot list changes from old to new: we can't update the cache, so we'll remove it
                            cachedLines.RemoveAt(i);
                        }
                        else
                        {
                            cachedLine = cachedLines[i];
                        }
                        break;
                    }
                }

                if (cachedLine != null && cachedLine.IsValid && newVersion.CompareAge(cachedLine.OldVersion) == 0)
                {
                    // the file hasn't changed since the cache was created, so just reuse the old highlighted line
                                        #if DEBUG
                    cachedLine.HighlightedLine.ValidateInvariants();
                                        #endif
                    return(cachedLine.HighlightedLine);
                }
            }

            bool wasInHighlightingGroup = inHighlightingGroup;
            if (!inHighlightingGroup)
            {
                BeginHighlighting();
            }
            try {
                return(DoHighlightLine(lineNumber, documentLine, cachedLine, newVersion));
            } finally {
                line = null;
                if (!wasInHighlightingGroup)
                {
                    EndHighlighting();
                }
            }
        }
Пример #3
0
 /// <summary>
 /// Compares currentVersion with version.
 /// -1 = currentVersion is older; 0 = same version; 1 = newVersion is older
 /// </summary>
 int CompareVersions(ITextSourceVersion newVersion)
 {
     if (currentVersion != null && newVersion != null && currentVersion.BelongsToSameDocumentAs(newVersion))
     {
         return(currentVersion.CompareAge(newVersion));
     }
     else
     {
         return(-1);
     }
 }
 /// <summary>
 /// Compares currentVersion with version.
 /// -1 = currentVersion is older; 0 = same version; 1 = newVersion is older
 /// </summary>
 int CompareVersions(ITextSourceVersion newVersion)
 {
     Debug.Assert(rwLock.IsReadLockHeld || rwLock.IsUpgradeableReadLockHeld || rwLock.IsWriteLockHeld);
     if (currentVersion != null && newVersion != null && currentVersion.BelongsToSameDocumentAs(newVersion))
     {
         return(currentVersion.CompareAge(newVersion));
     }
     else
     {
         return(-1);
     }
 }
        Task <ProjectEntry> DoParseAsync(ITextSource fileContent, IProject parentProject, bool requestFullParseInformation, CancellationToken cancellationToken)
        {
            // Create snapshot of file content, if required
            bool lookupOpenFileOnTargetThread;

            if (fileContent != null)
            {
                lookupOpenFileOnTargetThread = false;
                // File content was explicitly specified:
                // Let's make a snapshot in case the text source is mutable.
                fileContent = fileContent.CreateSnapshot();
            }
            else if (SD.MainThread.InvokeRequired)
            {
                // fileContent == null && not on the main thread:
                // Don't fetch the file content right now; if we need to SafeThreadCall() anyways,
                // it's better to do so from the background task.
                lookupOpenFileOnTargetThread = true;
            }
            else
            {
                // fileContent == null && we are on the main thread:
                // Let's look up the file in the list of open files right now
                // so that we don't need to SafeThreadCall() later on.
                lookupOpenFileOnTargetThread = false;
                if (parser != null)
                {
                    fileContent = parser.GetFileContent(fileName);
                }
            }
            Task <ProjectEntry> task;

            lock (runningAsyncParseLock) {
                if (fileContent != null)
                {
                    // Optimization:
                    // don't start a background task if fileContent was specified and up-to-date parse info is available
                    rwLock.EnterReadLock();
                    try {
                        int index             = FindIndexForProject(parentProject);
                        int versionComparison = CompareVersions(fileContent.Version);
                        if (versionComparison == 0 && index >= 0)
                        {
                            // Ensure we have parse info for the specified project (entry.UnresolvedFile is null for newly registered projects)
                            // If full parse info is requested, ensure we have full parse info.
                            if (entries[index].UnresolvedFile != null && !(requestFullParseInformation && entries[index].CachedParseInformation == null))
                            {
                                // We already have the requested version parsed, just return it:
                                return(Task.FromResult(entries[index]));
                            }
                        }
                    } finally {
                        rwLock.ExitReadLock();
                    }
                    // Optimization:
                    // if an equivalent task is already running, return that one instead
                    if (runningAsyncParseTask != null && (!requestFullParseInformation || runningAsyncParseFullInfoRequested) &&
                        runningAsyncParseProject == parentProject &&
                        runningAsyncParseFileContentVersion.BelongsToSameDocumentAs(fileContent.Version) &&
                        runningAsyncParseFileContentVersion.CompareAge(fileContent.Version) == 0)
                    {
                        return(runningAsyncParseTask);
                    }
                }
                task = new Task <ProjectEntry>(
                    delegate {
                    try {
                        if (lookupOpenFileOnTargetThread)
                        {
                            fileContent = SD.FileService.GetFileContentForOpenFile(fileName);
                        }
                        return(DoParse(fileContent, parentProject, requestFullParseInformation, cancellationToken));
                    } finally {
                        lock (runningAsyncParseLock) {
                            runningAsyncParseTask = null;
                            runningAsyncParseFileContentVersion = null;
                            runningAsyncParseProject            = null;
                        }
                    }
                }, cancellationToken);
                if (fileContent != null && fileContent.Version != null && !cancellationToken.CanBeCanceled)
                {
                    runningAsyncParseTask = task;
                    runningAsyncParseFileContentVersion = fileContent.Version;
                    runningAsyncParseProject            = parentProject;
                    runningAsyncParseFullInfoRequested  = requestFullParseInformation;
                }
            }
            task.Start();
            return(task);
        }
Пример #6
0
        Task RunUpdateTask(ITextSource input, IDocumentLine startLine, int endOffset, ITextSourceVersion textSourceVersion, CancellationToken token)
        {
            return(Task.Run(delegate {
                var matches = new List <(UrlType, Match, IDocumentLine)> ();
                var line = startLine;
                int o = 0;
                while (line != null && line.Offset <= endOffset)
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    string lineText = input.GetTextAt(line.Offset, line.Length);
                    var match = UrlRegex.Match(lineText);
                    while (match.Success)
                    {
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }
                        matches.Add((UrlType.Url, match, line));
                        o = match.Index + match.Length;
                        var len = line.Length - o;
                        if (len <= 0)
                        {
                            break;
                        }
                        match = UrlRegex.Match(lineText, o, len);
                    }

                    o = 0;
                    match = MailRegex.Match(lineText);
                    while (match.Success)
                    {
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }
                        matches.Add((UrlType.Email, match, line));
                        o = match.Index + match.Length;
                        var len = line.Length - o;
                        if (len <= 0)
                        {
                            break;
                        }
                        match = MailRegex.Match(lineText, o, len);
                    }
                    line = line.NextLine;
                }

                Runtime.RunInMainThread(delegate {
                    if (token.IsCancellationRequested || Editor == null)
                    {
                        return;
                    }
                    if (textSourceVersion.CompareAge(Editor.Version) != 0)
                    {
                        return;
                    }
                    line = startLine;
                    while (line != null && line.Offset <= endOffset)
                    {
                        foreach (var u in Editor.GetLineMarkers(line).OfType <IUrlTextLineMarker> ())
                        {
                            Editor.RemoveMarker(u);
                            markers.Remove(u);
                        }
                        line = line.NextLine;
                    }

                    foreach (var m in matches)
                    {
                        var startCol = m.Item2.Index;
                        var url = m.Item2.Value;
                        var marker = Editor.TextMarkerFactory.CreateUrlTextMarker(Editor, url, m.Item1, "url", startCol, startCol + m.Item2.Length);
                        markers.Add(marker);
                        Editor.AddMarker(m.Item3, marker);
                    }
                    src.Remove(startLine.Offset);
                });
            }));