Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory-5.5.0/Editor/TextSourceVersionProvider.cs @ 17197

Last change on this file since 17197 was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 4.2 KB
Line 
1// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4// software and associated documentation files (the "Software"), to deal in the Software
5// without restriction, including without limitation the rights to use, copy, modify, merge,
6// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7// to whom the Software is furnished to do so, subject to the following conditions:
8//
9// The above copyright notice and this permission notice shall be included in all copies or
10// substantial portions of the Software.
11//
12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17// DEALINGS IN THE SOFTWARE.
18
19using System;
20using System.Collections.Generic;
21using System.Diagnostics;
22using System.Linq;
23
24namespace ICSharpCode.NRefactory.Editor
25{
26  /// <summary>
27  /// Provides ITextSourceVersion instances.
28  /// </summary>
29  public class TextSourceVersionProvider
30  {
31    Version currentVersion;
32   
33    public TextSourceVersionProvider()
34    {
35      this.currentVersion = new Version(this);
36    }
37   
38    /// <summary>
39    /// Gets the current version.
40    /// </summary>
41    public ITextSourceVersion CurrentVersion {
42      get { return currentVersion; }
43    }
44   
45    /// <summary>
46    /// Replaces the current version with a new version.
47    /// </summary>
48    /// <param name="change">Change from current version to new version</param>
49    public void AppendChange(TextChangeEventArgs change)
50    {
51      if (change == null)
52        throw new ArgumentNullException("change");
53      currentVersion.change = change;
54      currentVersion.next = new Version(currentVersion);
55      currentVersion = currentVersion.next;
56    }
57   
58    [DebuggerDisplay("Version #{id}")]
59    sealed class Version : ITextSourceVersion
60    {
61      // Reference back to the provider.
62      // Used to determine if two checkpoints belong to the same document.
63      readonly TextSourceVersionProvider provider;
64      // ID used for CompareAge()
65      readonly int id;
66     
67      // the change from this version to the next version
68      internal TextChangeEventArgs change;
69      internal Version next;
70     
71      internal Version(TextSourceVersionProvider provider)
72      {
73        this.provider = provider;
74      }
75     
76      internal Version(Version prev)
77      {
78        this.provider = prev.provider;
79        this.id = unchecked( prev.id + 1 );
80      }
81     
82      public bool BelongsToSameDocumentAs(ITextSourceVersion other)
83      {
84        Version o = other as Version;
85        return o != null && provider == o.provider;
86      }
87     
88      public int CompareAge(ITextSourceVersion other)
89      {
90        if (other == null)
91          throw new ArgumentNullException("other");
92        Version o = other as Version;
93        if (o == null || provider != o.provider)
94          throw new ArgumentException("Versions do not belong to the same document.");
95        // We will allow overflows, but assume that the maximum distance between checkpoints is 2^31-1.
96        // This is guaranteed on x86 because so many checkpoints don't fit into memory.
97        return Math.Sign(unchecked( this.id - o.id ));
98      }
99     
100      public IEnumerable<TextChangeEventArgs> GetChangesTo(ITextSourceVersion other)
101      {
102        int result = CompareAge(other);
103        Version o = (Version)other;
104        if (result < 0)
105          return GetForwardChanges(o);
106        else if (result > 0)
107          return o.GetForwardChanges(this).Reverse().Select(change => change.Invert());
108        else
109          return EmptyList<TextChangeEventArgs>.Instance;
110      }
111     
112      IEnumerable<TextChangeEventArgs> GetForwardChanges(Version other)
113      {
114        // Return changes from this(inclusive) to other(exclusive).
115        for (Version node = this; node != other; node = node.next) {
116          yield return node.change;
117        }
118      }
119     
120      public int MoveOffsetTo(ITextSourceVersion other, int oldOffset, AnchorMovementType movement)
121      {
122        int offset = oldOffset;
123        foreach (var e in GetChangesTo(other)) {
124          offset = e.GetNewOffset(offset, movement);
125        }
126        return offset;
127      }
128    }
129  }
130}
Note: See TracBrowser for help on using the repository browser.