예제 #1
0
        public SourceLocation Translate(SourceLocation loc, int fromVersion, int toVersion)
        {
            var snapVer = _snapshots.Peek().Version;
            var fromVer = snapVer;

            while (fromVer.Next != null && fromVer.VersionNumber < fromVersion)
            {
                fromVer = fromVer.Next;
            }

            var toVer = toVersion > fromVersion ? fromVer : snapVer;

            while (toVer.Next != null && toVer.VersionNumber < toVersion)
            {
                toVer = toVer.Next;
            }

            var fromLines = GetLineLocations(fromVer.VersionNumber);
            var index     = NewLineLocation.LocationToIndex(fromLines, loc, fromVer.Length);

            if (fromVer.VersionNumber < toVer.VersionNumber)
            {
                index = Tracking.TrackPositionForwardInTime(PointTrackingMode.Negative, index, fromVer, toVer);
            }
            else
            {
                index = Tracking.TrackPositionBackwardInTime(PointTrackingMode.Negative, index, fromVer, toVer);
            }

            var toLines = GetLineLocations(toVer.VersionNumber);

            return(NewLineLocation.IndexToLocation(toLines, index));
        }
 public SourceSpan GetTokenSpan(IndexSpan span)
 {
     return(new SourceSpan(
                NewLineLocation.IndexToLocation(TokenNewlines, span.Start),
                NewLineLocation.IndexToLocation(TokenNewlines, span.End)
                ));
 }
 private SourceSpan GetTokenSpan(IndexSpan span)
 {
     EnsureTokens();
     return(new SourceSpan(
                NewLineLocation.IndexToLocation(_tokenNewlines, span.Start),
                NewLineLocation.IndexToLocation(_tokenNewlines, span.End)
                ));
 }
예제 #4
0
 internal void Add(string message, NewLineLocation[] lineLocations, int startIndex, int endIndex, int errorCode, Severity severity)
 {
     Add(
         message,
         new SourceSpan(NewLineLocation.IndexToLocation(lineLocations, startIndex), NewLineLocation.IndexToLocation(lineLocations, endIndex)),
         errorCode,
         severity
         );
 }
예제 #5
0
 public override void Add(string message, NewLineLocation[] lineLocations, int startIndex, int endIndex, int errorCode, Severity severity)
 {
     if (severity == Severity.Error || severity == Severity.FatalError)
     {
         _errors.Add(new ErrorResult(message, new SourceSpan(NewLineLocation.IndexToLocation(lineLocations, startIndex), NewLineLocation.IndexToLocation(lineLocations, endIndex))));
     }
     else if (severity == Severity.Warning)
     {
         _warnings.Add(new ErrorResult(message, new SourceSpan(NewLineLocation.IndexToLocation(lineLocations, startIndex), NewLineLocation.IndexToLocation(lineLocations, endIndex))));
     }
 }
예제 #6
0
 internal SourceLocation IndexToLocation(int index)
 {
     return(NewLineLocation.IndexToLocation(_lineLocations, index));
 }
예제 #7
0
        public SourceLocation GetSourceLocation(int index, int atVersion)
        {
            var lines = GetLineLocations(atVersion);

            return(NewLineLocation.IndexToLocation(lines, index));
        }
예제 #8
0
        internal NewLineLocation[] GetLineLocations(int version)
        {
            var ver = _snapshots.Peek().Version;

            NewLineLocation[] initial;

            lock (_lineCache) {
                // Precalculated for this version
                if (_lineCache.TryGetValue(version, out initial))
                {
                    return(initial);
                }

                // We simply can't provide these lines any more
                if (ver.VersionNumber > version)
                {
                    throw new NotSupportedException($"version {version} is no longer in memory");
                }

                int fromVersion = version;
                // Get the last available set of newlines
                while (--fromVersion >= ver.VersionNumber)
                {
                    if (_lineCache.TryGetValue(fromVersion, out initial))
                    {
                        break;
                    }
                }

                // Create the initial set if it wasn't cached
                if (initial == null)
                {
                    fromVersion             = ver.VersionNumber;
                    _lineCache[fromVersion] = initial = LinesToLineEnds(_snapshots.Peek().Lines).ToArray();
                }

                while (ver.Next != null && ver.VersionNumber < fromVersion)
                {
                    ver = ver.Next;
                }

#if DEBUG
                var appliedVersions = new List <ITextVersion>();
#endif
                List <NewLineLocation> asLengths = null;
                while (ver.Changes != null && ver.VersionNumber < version)
                {
#if DEBUG
                    appliedVersions.Add(ver);
#endif
                    if (asLengths == null)
                    {
                        asLengths = LineEndsToLineLengths(initial).ToList();
                    }

                    // Apply the changes from this version to the line lengths
                    foreach (var c in ver.Changes.Reverse())
                    {
                        var oldLoc = NewLineLocation.IndexToLocation(initial, c.OldPosition);
                        int lineNo = oldLoc.Line - 1;
                        while (asLengths.Count <= lineNo)
                        {
                            asLengths.Add(new NewLineLocation(0, NewLineKind.None));
                        }

                        if (c.OldLength > 0)
                        {
                            var line = asLengths[lineNo];
                            // Deletion may span lines, so combine them until we can delete
                            int cutAtCol = oldLoc.Column - 1;
                            for (int toRemove = c.OldLength; lineNo < asLengths.Count; lineNo += 1)
                            {
                                line = asLengths[lineNo];
                                int lineLen = line.EndIndex - cutAtCol;
                                cutAtCol = 0;
                                if (line.Kind == NewLineKind.CarriageReturnLineFeed && toRemove == lineLen - 1)
                                {
                                    // Special case of deleting just the '\r' from a '\r\n' ending
                                    asLengths[lineNo] = new NewLineLocation(line.EndIndex - toRemove, NewLineKind.LineFeed);
                                    break;
                                }
                                else if (toRemove < lineLen)
                                {
                                    asLengths[lineNo] = new NewLineLocation(line.EndIndex - toRemove, line.Kind);
                                    break;
                                }
                                else
                                {
                                    asLengths[lineNo] = new NewLineLocation(line.EndIndex - lineLen, NewLineKind.None);
                                    toRemove         -= lineLen;
                                    if (toRemove <= 0)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        lineNo = oldLoc.Line - 1;
                        if (!string.IsNullOrEmpty(c.NewText))
                        {
                            var             line = asLengths[lineNo];
                            NewLineLocation addedLine = new NewLineLocation(0, NewLineKind.None);
                            int             lastLineEnd = 0, cutAtCol = oldLoc.Column - 1;
                            if (cutAtCol > line.EndIndex - line.Kind.GetSize() && lineNo + 1 < asLengths.Count)
                            {
                                cutAtCol = 0;
                                lineNo  += 1;
                                line     = asLengths[lineNo];
                            }
                            while ((addedLine = NewLineLocation.FindNewLine(c.NewText, lastLineEnd)).Kind != NewLineKind.None)
                            {
                                if (cutAtCol > 0)
                                {
                                    asLengths[lineNo] = new NewLineLocation(line.EndIndex - cutAtCol, line.Kind);
                                    lastLineEnd      -= cutAtCol;
                                    cutAtCol          = 0;
                                }
                                line = new NewLineLocation(addedLine.EndIndex - lastLineEnd, addedLine.Kind);
                                asLengths.Insert(lineNo++, line);
                                lastLineEnd = addedLine.EndIndex;
                            }
                            if (addedLine.EndIndex > lastLineEnd)
                            {
                                if (lineNo < asLengths.Count)
                                {
                                    line = asLengths[lineNo];
                                    asLengths[lineNo] = line = new NewLineLocation(line.EndIndex + addedLine.EndIndex - lastLineEnd, line.Kind);
                                }
                                else
                                {
                                    asLengths.Add(new NewLineLocation(addedLine.EndIndex - lastLineEnd, NewLineKind.None));
                                }
                            }
                        }
                    }

                    initial = LineLengthsToLineEnds(asLengths).ToArray();
                    if (asLengths.Count != initial.Length)
                    {
                        asLengths = null;
                    }
                    _lineCache[ver.VersionNumber + 1] = initial;

#if DEBUG
                    if (System.Diagnostics.Debugger.IsAttached && initial.Length > 0 && ver.Next != null && initial.Last().EndIndex != ver.Next.Length)
                    {
                        // Line calculations were wrong
                        // Asserts do not work properly here, so we just break if the debugger is attached
                        System.Diagnostics.Debugger.Break();
                    }
#endif

                    ver = ver.Next;
                }

                return(initial);
            }
        }
예제 #9
0
 public override SourceLocation IndexToLocation(int index) => NewLineLocation.IndexToLocation(_newLines, index);
예제 #10
0
 public SourceLocation IndexToLocation(int index) => NewLineLocation.IndexToLocation(NewLineLocations, index);