public TrackedSegment(DocumentScript script, int originalStart, int originalEnd)
 {
     this.script          = script;
     this.originalVersion = script.currentDocument.Version;
     this.originalStart   = originalStart;
     this.originalEnd     = originalEnd;
 }
示例#2
0
		/// <summary>
		/// Creates a new RopeTextSource.
		/// </summary>
		public RopeTextSource(Rope<char> rope, ITextSourceVersion version)
		{
			if (rope == null)
				throw new ArgumentNullException("rope");
			this.rope = rope.Clone();
			this.version = version;
		}
示例#3
0
        List <InternalObject> InternalParseIncremental(
            IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState,
            bool collapseProperlyNestedElements, CancellationToken cancellationToken)
        {
            var reader = new TagReader(this, newTextSource, collapseProperlyNestedElements);
            ITextSourceVersion newVersion = newTextSource.Version;
            var reuseMap = oldParserState != null?oldParserState.GetReuseMapTo(newVersion) : null;

            List <InternalObject> internalObjects;

            if (reuseMap != null)
            {
                internalObjects = reader.ReadAllObjectsIncremental(oldParserState.Objects, reuseMap, cancellationToken);
            }
            else
            {
                internalObjects = reader.ReadAllObjects(cancellationToken);
            }

            if (newVersion != null)
            {
                newParserState = new IncrementalParserState(newTextSource.TextLength, newVersion, internalObjects.ToArray());
            }
            else
            {
                newParserState = null;
            }

            return(internalObjects);
        }
			public bool BelongsToSameDocumentAs(ITextSourceVersion other)
			{
				if (other == null)
					throw new ArgumentNullException("other");
				Version o = other as Version;
				return o != null && provider == o.provider;
			}
示例#5
0
 public CachedLine(HighlightedLine highlightedLine, ITextSourceVersion fileVersion)
 {
     HighlightedLine = highlightedLine ?? throw new ArgumentNullException(nameof(highlightedLine));
     OldVersion      = fileVersion ?? throw new ArgumentNullException(nameof(fileVersion));
     IsValid         = true;
     Offset          = HighlightedLine.DocumentLine.Offset;
 }
        public void RegisterUnresolvedFile(IProject project, IUnresolvedFile unresolvedFile)
        {
            if (project == null)
            {
                throw new ArgumentNullException("project");
            }
            if (unresolvedFile == null)
            {
                throw new ArgumentNullException("unresolvedFile");
            }
            FreezableHelper.Freeze(unresolvedFile);
            var newParseInfo = new ParseInformation(unresolvedFile, null, false);

            rwLock.EnterWriteLock();
            try {
                int index = FindIndexForProject(project);
                if (index >= 0)
                {
                    currentVersion = null;
                    var args = new ParseInformationEventArgs(project, entries[index].UnresolvedFile, newParseInfo);
                    entries[index] = new ProjectEntry(project, unresolvedFile, null);
                    project.OnParseInformationUpdated(args);
                    parserService.RaiseParseInformationUpdated(args);
                }
            } finally {
                rwLock.ExitWriteLock();
            }
        }
示例#7
0
        public MdTextViewLineCollection(MonoTextEditor textEditor) : base(64)
        {
            this.textView = textEditor;
            this.version  = this.textView.Document.Version;

            int    startLine = textEditor.TextArea.YToLine(textEditor.VAdjustment.Value);
            double startY    = textEditor.TextArea.LineToY(startLine);
            double curY      = startY;
            double lastY     = textEditor.VAdjustment.Value + textEditor.Allocation.Height;

            for (int visualLineNumber = textEditor.GetTextEditorData().LogicalToVisualLine(startLine); ; visualLineNumber++)
            {
                int logicalLineNumber = textEditor.GetTextEditorData().VisualToLogicalLine(visualLineNumber);
                var line = textEditor.GetLine(logicalLineNumber);

                if (line == null)
                {
                    break;
                }

                Add(new MdTextViewLine(this, textEditor, line, textEditor.TextViewMargin.GetLayout(line)));

                curY += textEditor.TextArea.GetLineHeight(line);
                if (curY >= lastY)
                {
                    break;
                }
            }
        }
            public void Update(ITextSourceVersion newVersion)
            {
                // Apply document changes to all highlighting sections:
                foreach (TextChangeEventArgs change in OldVersion.GetChangesTo(newVersion))
                {
                    foreach (HighlightedSection section in HighlightedLine.Sections)
                    {
                        int endOffset = section.Offset + section.Length;
                        section.Offset = change.GetNewOffset(section.Offset);
                        endOffset      = change.GetNewOffset(endOffset);
                        section.Length = endOffset - section.Offset;
                    }
                }
                // The resulting sections might have become invalid:
                // - zero-length if section was deleted,
                // - a section might have moved outside the range of this document line (newline inserted in document = line split up)
                // So we will remove all highlighting sections which have become invalid.
                int lineStart = HighlightedLine.DocumentLine.Offset;
                int lineEnd   = lineStart + HighlightedLine.DocumentLine.Length;

                for (int i = 0; i < HighlightedLine.Sections.Count; i++)
                {
                    HighlightedSection section = HighlightedLine.Sections[i];
                    if (section.Offset < lineStart || section.Offset + section.Length > lineEnd || section.Length <= 0)
                    {
                        HighlightedLine.Sections.RemoveAt(i--);
                    }
                }

                this.OldVersion = newVersion;
                this.IsValid    = false;
            }
		/// <summary>
		/// Creates a new StringTextSource with the given text.
		/// </summary>
		public StringTextSource(string text, ITextSourceVersion version)
		{
			if (text == null)
				throw new ArgumentNullException("text");
			this.text = text;
			this.version = version;
		}
示例#10
0
 public int MoveOffsetTo(ITextSourceVersion other, int oldOffset, AnchorMovementType movement)
 {
     if (this != other)
     {
         throw new ArgumentException("other belongs to different document");
     }
     return(oldOffset);
 }
示例#11
0
 public IEnumerable <TextChangeEventArgs> GetChangesTo(ITextSourceVersion other)
 {
     if (this != other)
     {
         throw new ArgumentException("other belongs to different document");
     }
     return(EmptyList <TextChangeEventArgs> .Instance);
 }
示例#12
0
 public int CompareAge(ITextSourceVersion other)
 {
     if (this != other)
     {
         throw new ArgumentException("other belongs to different document");
     }
     return(0);
 }
 public MdTextViewLineCollection(MonoTextEditor textEditor) : base(64)
 {
     this.textEditor = textEditor;
     this.version    = this.textEditor.Document.Version;
     textEditor.TextViewModel.VisualBuffer.ChangedLowPriority += OnVisualBufferChanged;
     textEditor.TextViewModel.VisualBuffer.ContentTypeChanged += OnVisualBufferContentTypeChanged;
     textEditor.Closed += TextEditorClosed;
 }
示例#14
0
		internal void SetEditor(TextEditor editor)
		{
			if (editor == null)
				throw new ArgumentNullException (nameof (editor));
			this.editor = editor;
			this.version = editor.Version;
			OnEditorSet ();
		}
 void Editor_EndAtomicUndoOperation(object sender, EventArgs e)
 {
     if (beginVersion != null && beginVersion.CompareAge(Editor.Version) != 0)
     {
         RemoveWidget();
     }
     beginVersion = null;
 }
示例#16
0
 public ParseInformation(IUnresolvedFile unresolvedFile, ITextSourceVersion parsedVersion, bool isFullParseInformation)
 {
     if (unresolvedFile == null)
         throw new ArgumentNullException("unresolvedFile");
     this.unresolvedFile = unresolvedFile;
     this.parsedVersion = parsedVersion;
     this.isFullParseInformation = isFullParseInformation;
 }
		public CSharpFullParseInformation(CSharpUnresolvedFile unresolvedFile, ITextSourceVersion parsedVersion, SyntaxTree compilationUnit)
			: base(unresolvedFile, parsedVersion, isFullParseInformation: true)
		{
			if (unresolvedFile == null)
				throw new ArgumentNullException("unresolvedFile");
			if (compilationUnit == null)
				throw new ArgumentNullException("compilationUnit");
			this.syntaxTree = compilationUnit;
		}
示例#18
0
 /// <summary>
 /// Creates a new RopeTextSource.
 /// </summary>
 public RopeTextSource(Rope <char> rope, ITextSourceVersion version)
 {
     if (rope == null)
     {
         throw new ArgumentNullException("rope");
     }
     this.rope    = rope.Clone();
     this.version = version;
 }
		/// <summary>
		/// Creates a new StringTextSource with the given text.
		/// </summary>
		public StringTextSource (string text, ITextSourceVersion version, Encoding encoding = null, bool useBom = true)
		{
			if (text == null)
				throw new ArgumentNullException ("text");
			this.text = text;
			this.version = version;
			this.UseBOM = useBom;
			this.Encoding = encoding ?? Encoding.UTF8;
		}
示例#20
0
 /// <summary>
 ///     Creates a new StringTextSource with the given text.
 /// </summary>
 public StringTextSource(string text, ITextSourceVersion version)
 {
     if (text == null)
     {
         throw new ArgumentNullException("text");
     }
     Text    = text;
     Version = version;
 }
		public TextFileNavigationPoint (Document doc, TextEditor buffer)
			: base (doc)
		{
			var location = buffer.CaretLocation;
			version = buffer.Version;
			line = location.Line;
			column = location.Column;
			offset = buffer.CaretOffset;
		}
		public ImmutableTextTextSource (ImmutableText immutableText, System.Text.Encoding encoding, bool useBom, ITextSourceVersion version = null)
		{
			if (immutableText == null)
				throw new ArgumentNullException (nameof (immutableText));
			this.immutableText = immutableText;
			this.encoding = encoding;
			UseBOM = useBom;
			this.version = version;
		}
        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();
                }
            }
        }
示例#24
0
            public int MoveOffsetTo(ITextSourceVersion other, int oldOffset, AnchorMovementType movement)
            {
                int offset = oldOffset;

                foreach (var e in GetChangesTo(other))
                {
                    offset = e.GetNewOffset(offset, movement);
                }
                return(offset);
            }
 public PatchedFile(FileName fileName, IReadOnlyList<SearchResultMatch> matches, ITextSourceVersion oldVersion, ITextSourceVersion newVersion)
     : base(fileName, matches)
 {
     if (oldVersion == null)
         throw new ArgumentNullException("oldVersion");
     if (newVersion == null)
         throw new ArgumentNullException("newVersion");
     this.oldVersion = oldVersion;
     this.newVersion = newVersion;
 }
示例#26
0
 internal void SetEditor(TextEditor editor)
 {
     if (editor == null)
     {
         throw new ArgumentNullException(nameof(editor));
     }
     this.editor  = editor;
     this.version = editor.Version;
     OnEditorSet();
 }
示例#27
0
        public TextFileNavigationPoint(Document doc, TextEditor buffer)
            : base(doc)
        {
            var location = buffer.CaretLocation;

            version = buffer.Version;
            line    = location.Line;
            column  = location.Column;
            offset  = buffer.CaretOffset;
        }
 public MdTextViewLineCollection(MonoTextEditor textEditor) : base(64)
 {
     this.textEditor = textEditor;
     this.version    = this.textEditor.Document.Version;
     textEditor.TextViewModel.VisualBuffer.ChangedLowPriority += OnVisualBufferChanged;
     textEditor.Closed += (sender, args) => {
         var editor = (MonoTextEditor)sender;
         editor.TextViewModel.VisualBuffer.ChangedLowPriority -= OnVisualBufferChanged;
     };
 }
 public ParseInformation(IUnresolvedFile unresolvedFile, ITextSourceVersion parsedVersion, bool isFullParseInformation)
 {
     if (unresolvedFile == null)
     {
         throw new ArgumentNullException("unresolvedFile");
     }
     this.unresolvedFile         = unresolvedFile;
     this.parsedVersion          = parsedVersion;
     this.isFullParseInformation = isFullParseInformation;
 }
示例#30
0
            public bool BelongsToSameDocumentAs(ITextSourceVersion other)
            {
                if (other == null)
                {
                    throw new ArgumentNullException("other");
                }
                Version o = other as Version;

                return(o != null && provider == o.provider);
            }
示例#31
0
 /// <summary>
 /// Creates a new StringTextSource with the given text.
 /// </summary>
 public StringTextSource(string text, ITextSourceVersion version, Encoding encoding = null, bool useBom = true)
 {
     if (text == null)
     {
         throw new ArgumentNullException("text");
     }
     this.text     = text;
     this.version  = version;
     this.Encoding = encoding ?? (useBom ? Encoding.UTF8 : TextFileUtility.DefaultEncoding);
 }
示例#32
0
 /// <summary>
 /// Creates a new StringTextSource with the given text.
 /// </summary>
 public StringTextSource(string text, ITextSourceVersion version, Encoding encoding = null)
 {
     if (text == null)
     {
         throw new ArgumentNullException("text");
     }
     this.text     = text;
     this.version  = version;
     this.Encoding = encoding ?? Encoding.UTF8;
 }
			public int CompareAge(ITextSourceVersion other)
			{
				if (other == null)
					throw new ArgumentNullException("other");
				var o = other as Version;
				if (o == null || provider != o.provider)
					throw new ArgumentException("Versions do not belong to the same document.");
				// We will allow overflows, but assume that the maximum distance between checkpoints is 2^31-1.
				// This is guaranteed on x86 because so many checkpoints don't fit into memory.
				return Math.Sign(unchecked(id - o.id));
			}
示例#34
0
        public TextLinkEditMode(MonoTextEditor editor, int baseOffset, List <TextLink> links)
        {
            this.editor             = editor;
            this.links              = links;
            this.baseOffset         = baseOffset;
            this.SetCaretPosition   = true;
            this.caretOffset        = editor.Caret.Offset;
            this.caretOffsetVersion = editor.Document.Version;

            this.SelectPrimaryLink = true;
        }
示例#35
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);
     }
 }
 public ImmutableTextTextSource(ImmutableText immutableText, System.Text.Encoding encoding, bool useBom, ITextSourceVersion version = null)
 {
     if (immutableText == null)
     {
         throw new ArgumentNullException(nameof(immutableText));
     }
     this.immutableText = immutableText;
     this.encoding      = encoding;
     UseBOM             = useBom;
     this.version       = version;
 }
示例#37
0
 void Clear()
 {
     if (existingResults != null)
     {
         foreach (var oldResult in existingResults)
         {
             oldResult.RemoveMarker();
         }
         existingResults = null;
     }
     analyzedVersion = null;
 }
 /// <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);
     }
 }
        protected override void OnDocumentClosing()
        {
            // text source version becomes invalid on document close.
            var editor = Document.Editor;

            offset = version.MoveOffsetTo(editor.Version, offset);
            var location = editor.CaretLocation;

            line    = location.Line;
            column  = location.Column;
            version = null;
        }
示例#40
0
		internal List<UnchangedSegment> GetReuseMapTo(ITextSourceVersion newVersion)
		{
			ITextSourceVersion oldVersion = this.Version;
			if (oldVersion == null || newVersion == null)
				return null;
			if (!oldVersion.BelongsToSameDocumentAs(newVersion))
				return null;
			List<UnchangedSegment> reuseMap = new List<UnchangedSegment>();
			reuseMap.Add(new UnchangedSegment(0, 0, this.TextLength));
			foreach (var change in oldVersion.GetChangesTo(newVersion)) {
				bool needsSegmentRemoval = false;
				for (int i = 0; i < reuseMap.Count; i++) {
					UnchangedSegment segment = reuseMap[i];
					if (segment.NewOffset + segment.Length <= change.Offset) {
						// change is completely after this segment
						continue;
					}
					if (change.Offset + change.RemovalLength <= segment.NewOffset) {
						// change is completely before this segment
						segment.NewOffset += change.InsertionLength - change.RemovalLength;
						reuseMap[i] = segment;
						continue;
					}
					// Change is overlapping segment.
					// Split segment into two parts: the part before change, and the part after change.
					var segmentBefore = new UnchangedSegment(segment.OldOffset, segment.NewOffset, change.Offset - segment.NewOffset);
					Debug.Assert(segmentBefore.Length < segment.Length);
					
					int lengthAtEnd = segment.NewOffset + segment.Length - (change.Offset + change.RemovalLength);
					var segmentAfter = new UnchangedSegment(
						segment.OldOffset + segment.Length - lengthAtEnd,
						change.Offset + change.InsertionLength,
						lengthAtEnd);
					Debug.Assert(segmentAfter.Length < segment.Length);
					Debug.Assert(segmentBefore.Length + segmentAfter.Length <= segment.Length);
					Debug.Assert(segmentBefore.NewOffset + segmentBefore.Length <= segmentAfter.NewOffset);
					Debug.Assert(segmentBefore.OldOffset + segmentBefore.Length <= segmentAfter.OldOffset);
					if (segmentBefore.Length > 0 && segmentAfter.Length > 0) {
						reuseMap[i] = segmentBefore;
						reuseMap.Insert(++i, segmentAfter);
					} else if (segmentBefore.Length > 0) {
						reuseMap[i] = segmentBefore;
					} else {
						reuseMap[i] = segmentAfter;
						if (segmentAfter.Length <= 0)
							needsSegmentRemoval = true;
					}
				}
				if (needsSegmentRemoval)
					reuseMap.RemoveAll(s => s.Length <= 0);
			}
			return reuseMap;
		}
示例#41
0
        public ParseInformation GetCachedParseInformation(FileName fileName, ITextSourceVersion version, IProject parentProject)
        {
            var entry = GetFileEntry(fileName, false);

            if (entry != null)
            {
                return(entry.GetCachedParseInformation(version, parentProject));
            }
            else
            {
                return(null);
            }
        }
示例#42
0
            public InspectionTag(IssueManager manager, IssueProvider provider, ITextSourceVersion inspectedVersion, string description, int startOffset, int endOffset, IssueMarker markerType, IEnumerable <CodeAction> actions)
            {
                this.manager          = manager;
                this.Provider         = provider;
                this.InspectedVersion = inspectedVersion;
                this.Description      = description;
                this.StartOffset      = startOffset;
                this.EndOffset        = endOffset;
                this.Severity         = provider.CurrentSeverity;
                this.MarkerType       = markerType;

                this.Actions = actions.Select(Wrap).ToList();
            }
		public ParseInformation GetCachedParseInformation(ITextSourceVersion version, IProject parentProject)
		{
			lock (this) {
				if (version != null && CompareVersions(version) != 0) {
					return null;
				}
				int index = FindIndexForProject(parentProject);
				if (index < 0)
					return null;
				return entries[index].CachedParseInformation;
			}
		}
		public IUnresolvedFile GetExistingUnresolvedFile(ITextSourceVersion version, IProject parentProject)
		{
			lock (this) {
				if (version != null && CompareVersions(version) != 0) {
					return null;
				}
				int index = FindIndexForProject(parentProject);
				if (index < 0)
					return null;
				return entries[index].UnresolvedFile;
			}
		}
		public void ExpireCache()
		{
			lock (this) {
				if (PrimaryProject == null) {
					parserService.RemoveEntry(this);
				} else {
					for (int i = 0; i < entries.Count; i++) {
						var oldEntry = entries[i];
						entries[i] = new ProjectEntry(oldEntry.Project, oldEntry.UnresolvedFile, null);
					}
				}
				// force re-parse on next ParseFile() call even if unchanged
				this.currentVersion = null;
			}
		}
		/// <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;
		}
示例#47
0
		public IUnresolvedFile GetExistingUnresolvedFile(FileName fileName, ITextSourceVersion version, IProject parentProject)
		{
			var entry = GetFileEntry(fileName, false);
			if (entry != null)
				return entry.GetExistingUnresolvedFile(version, parentProject);
			else
				return null;
		}
		public void RegisterUnresolvedFile(IProject project, IUnresolvedFile unresolvedFile)
		{
			if (project == null)
				throw new ArgumentNullException("project");
			if (unresolvedFile == null)
				throw new ArgumentNullException("unresolvedFile");
			FreezableHelper.Freeze(unresolvedFile);
			var newParseInfo = new ParseInformation(unresolvedFile, null, false);
			lock (this) {
				int index = FindIndexForProject(project);
				if (index >= 0) {
					currentVersion = null;
					var args = new ParseInformationEventArgs(project, entries[index].UnresolvedFile, newParseInfo);
					entries[index] = new ProjectEntry(project, unresolvedFile, null);
					project.OnParseInformationUpdated(args);
					parserService.RaiseParseInformationUpdated(args);
				}
			}
		}
		ProjectEntry DoParse(ITextSource fileContent, IProject parentProject, bool fullParseInformationRequested,
		                     CancellationToken cancellationToken)
		{
			if (parser == null)
				return default(ProjectEntry);
			
			if (fileContent == null) {
				// No file content was specified. Because the callers of this method already check for currently open files,
				// we can assume that the file isn't open and simply read it from disk.
				try {
					fileContent = SD.FileService.GetFileContentFromDisk(fileName, cancellationToken);
				} catch (IOException) {
					// It is possible that the file gets deleted/becomes inaccessible while a background parse
					// operation is enqueued, so we have to handle IO exceptions.
					return default(ProjectEntry);
				} catch (UnauthorizedAccessException) {
					return default(ProjectEntry);
				}
			}
			
			ProjectEntry result;
			lock (this) {
				int index = FindIndexForProject(parentProject);
				int versionComparison = CompareVersions(fileContent.Version);
				if (versionComparison > 0 || index < 0) {
					// We're going backwards in time, or are requesting a project that is not an owner
					// for this entry.
					var parseInfo = ParseWithExceptionHandling(fileContent, fullParseInformationRequested, parentProject, cancellationToken);
					FreezableHelper.Freeze(parseInfo.UnresolvedFile);
					return new ProjectEntry(parentProject, parseInfo.UnresolvedFile, parseInfo);
				} else {
					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 && !(fullParseInformationRequested && entries[index].CachedParseInformation == null)) {
							// We already have the requested version parsed, just return it:
							return entries[index];
						}
					}
				}
				
				ParseInformationEventArgs[] results = new ParseInformationEventArgs[entries.Count];
				for (int i = 0; i < entries.Count; i++) {
					var parseInfo = ParseWithExceptionHandling(fileContent, fullParseInformationRequested, entries[i].Project, cancellationToken);
					if (parseInfo == null)
						throw new NullReferenceException(parser.GetType().Name + ".Parse() returned null");
					if (fullParseInformationRequested && !parseInfo.IsFullParseInformation)
						throw new InvalidOperationException(parser.GetType().Name + ".Parse() did not return full parse info as requested.");
					OnDiskTextSourceVersion onDiskVersion = fileContent.Version as OnDiskTextSourceVersion;
					if (onDiskVersion != null)
						parseInfo.UnresolvedFile.LastWriteTime = onDiskVersion.LastWriteTime;
					FreezableHelper.Freeze(parseInfo.UnresolvedFile);
					results[i] = new ParseInformationEventArgs(entries[i].Project, entries[i].UnresolvedFile, parseInfo);
				}
				
				// Only if all parse runs succeeded, register the parse information.
				currentVersion = fileContent.Version;
				for (int i = 0; i < entries.Count; i++) {
					if (fullParseInformationRequested || (entries[i].CachedParseInformation != null && results[i].NewParseInformation.IsFullParseInformation))
						entries[i] = new ProjectEntry(entries[i].Project, results[i].NewUnresolvedFile, results[i].NewParseInformation);
					else
						entries[i] = new ProjectEntry(entries[i].Project, results[i].NewUnresolvedFile, null);
					if (entries[i].Project != null)
						entries[i].Project.OnParseInformationUpdated(results[i]);
					parserService.RaiseParseInformationUpdated(results[i]);
				}
				result = entries[index];
			}  // exit lock
			parserService.RegisterForCacheExpiry(this);
			return result;
		}
示例#50
0
			public SnapshotDocument (string text, ITextSourceVersion version) : base (new StringBuffer (text), new PrimitiveLineSplitter ())
			{
				this.version = version;
				Text = text;
				ReadOnly = true;
			}
            public CachedLine(HighlightedLine highlightedLine, ITextSourceVersion fileVersion)
            {
                if (highlightedLine == null)
                    throw new ArgumentNullException(nameof(highlightedLine));
                if (fileVersion == null)
                    throw new ArgumentNullException(nameof(fileVersion));

                HighlightedLine = highlightedLine;
                OldVersion = fileVersion;
                IsValid = true;
            }
			public int MoveOffsetTo(ITextSourceVersion other, int oldOffset, AnchorMovementType movement)
			{
				int offset = oldOffset;
				foreach (var e in GetChangesTo(other)) {
					offset = e.GetNewOffset(offset, movement);
				}
				return offset;
			}
			public bool BelongsToSameDocumentAs(ITextSourceVersion other)
			{
				Version o = other as Version;
				return o != null && provider == o.provider;
			}
示例#54
0
		public ParseInformation GetCachedParseInformation(FileName fileName, ITextSourceVersion version, IProject parentProject)
		{
			var entry = GetFileEntry(fileName, false);
			if (entry != null)
				return entry.GetCachedParseInformation(version, parentProject);
			else
				return null;
		}
		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;
				fileContent = parser.GetFileContent(fileName);
			}
			Task<ProjectEntry> task;
			lock (this) {
				if (fileContent != null) {
					// Optimization:
					// don't start a background task if fileContent was specified and up-to-date parse info is available
					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]);
						}
					}
					// 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 (this) {
								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;
		}
示例#56
0
		internal void UpdateCaretPosition ()
		{
			var curVersion = TextEditorData.Version;
			if (offsetVersion == null) {
				offsetVersion = curVersion;
				return;
			}
			var newOffset = offsetVersion.MoveOffsetTo (curVersion, caretOffset);
			offsetVersion = curVersion;
			if (newOffset == caretOffset || !AutoUpdatePosition)
				return;
			DocumentLocation old = Location;
			var newLocation = TextEditorData.OffsetToLocation (newOffset);
			int newColumn = newLocation.Column;
			
			var curLine = TextEditorData.GetLine (newLocation.Line);
			if (TextEditorData.HasIndentationTracker && TextEditorData.Options.IndentStyle == IndentStyle.Virtual && curLine.Length == 0) {
				if (column > DocumentLocation.MinColumn) {
					var indentColumn = TextEditorData.GetVirtualIndentationColumn (Location);
					newColumn = indentColumn;
				}
			}
			if (AllowCaretBehindLineEnd) {
				if (curLine != null && column > curLine.Length)
					newColumn = column;
			}

			line = newLocation.Line;
			column = newColumn;

			SetDesiredColumn ();
			UpdateCaretOffset ();
			OnPositionChanged (new DocumentLocationEventArgs (old));
		}
示例#57
0
		public void UpdateCaretOffset ()
		{
			int result = 0;
			var doc = TextEditorData.Document;
			if (doc == null)
				return;
			if (Line <= doc.LineCount) {
				DocumentLine line = doc.GetLine (Line);
				if (line != null) {
					result = line.Offset;
					result += System.Math.Min (Column - 1, line.Length);
				}
			}
			caretOffset = result;
			offsetVersion = doc.Version;
		}
			public IEnumerable<TextChangeEventArgs> GetChangesTo(ITextSourceVersion other)
			{
				int result = CompareAge(other);
				Version o = (Version)other;
				if (result < 0)
					return GetForwardChanges(o);
				else if (result > 0)
					return o.GetForwardChanges(this).Reverse().Select(change => change.Invert());
				else
					return EmptyList<TextChangeEventArgs>.Instance;
			}
示例#59
0
		public void SetDocument (TextDocument doc)
		{
			line = column = 1;
			offsetVersion = doc.Version;
			caretOffset = 0;
		}
		// Steps to load the designer:
		// - Parse main file
		// - Find other files containing parts of the form
		// - Parse all files and look for fields (for controls) and InitializeComponents method
		// - Create CodeDom objects for fields and InitializeComponents statements
		// - If debug build and Ctrl pressed, output CodeDom to console
		// - Return CodeDom objects to the .NET designer
		protected override CodeCompileUnit Parse()
		{
			SD.Log.Debug("CSharpDesignerLoader.Parse()");
			
			lastTextContentVersion = context.DesignerCodeFileDocument.Version;
			var primaryParseInfo = context.GetPrimaryFileParseInformation();
			var compilation = context.GetCompilation();
			
			// Find designer class
			ITypeDefinition designerClass = FormsDesignerSecondaryDisplayBinding.GetDesignableClass(primaryParseInfo.UnresolvedFile, compilation, out primaryPart);
			IMethod initializeComponents = FormsDesignerSecondaryDisplayBinding.GetInitializeComponents(designerClass);
			
			if (initializeComponents == null) {
				throw new FormsDesignerLoadException("The InitializeComponent method was not found. Designer cannot be loaded.");
			}
			Debug.Assert(primaryPart != null);
			Debug.Assert(designerClass != null);
			
			bool isFirstClassInFile = primaryParseInfo.UnresolvedFile.TopLevelTypeDefinitions[0] == primaryPart;
			
			// TODO: translate
			const string missingReferenceMessage = "Your project is missing a reference to '${Name}' - please add it using 'Project > Add Reference'.";
			if (compilation.FindType(typeof(System.Drawing.Point)).Kind == TypeKind.Unknown) {
				throw new FormsDesignerLoadException(StringParser.Parse(missingReferenceMessage, new StringTagPair("Name", "System.Drawing")));
			}
			if (compilation.FindType(typeof(System.Windows.Forms.Form)).Kind == TypeKind.Unknown) {
				throw new FormsDesignerLoadException(StringParser.Parse(missingReferenceMessage, new StringTagPair("Name" , "System.Windows.Forms")));
			}
			
			CodeDomConvertVisitor cv = new CodeDomConvertVisitor();
			cv.UseFullyQualifiedTypeNames = true;
			
			CSharpFullParseInformation designerParseInfo;
			MethodDeclaration initializeComponentsDeclaration = initializeComponents.GetDeclaration(out designerParseInfo) as MethodDeclaration;
			if (initializeComponentsDeclaration == null)
				throw new FormsDesignerLoadException("Could not find source code for InitializeComponents");
			var resolver = designerParseInfo.GetResolver(compilation);
			var codeMethod = (CodeMemberMethod) cv.Convert(initializeComponentsDeclaration, resolver);
			var codeClass = new CodeTypeDeclaration(designerClass.Name);
			codeClass.Attributes = MemberAttributes.Public;
			codeClass.BaseTypes.AddRange(designerClass.DirectBaseTypes.Select(cv.Convert).ToArray());
			codeClass.Members.Add(codeMethod);
			
			foreach (var field in designerClass.Fields) {
				var codeField = new CodeMemberField(cv.Convert(field.Type), field.Name);
				codeClass.Members.Add(codeField);
			}
			var codeNamespace = new CodeNamespace(designerClass.Namespace);
			codeNamespace.Types.Add(codeClass);
			var codeUnit = new CodeCompileUnit();
			codeUnit.Namespaces.Add(codeNamespace);
			
			// output generated CodeDOM to the console :
			#if DEBUG
			if ((Control.ModifierKeys & Keys.Control) == Keys.Control) {
				CodeDomVerboseOutputGenerator outputGenerator = new CodeDomVerboseOutputGenerator();
				outputGenerator.GenerateCodeFromMember(codeMethod, Console.Out, null);
				this.CodeDomProvider.GenerateCodeFromCompileUnit(codeUnit, Console.Out, null);
			}
			#endif
			
			LoggingService.Debug("NRefactoryDesignerLoader.Parse() finished");
			
			if (!isFirstClassInFile) {
				MessageService.ShowWarning("The form must be the first class in the file in order for form resources to be compiled correctly.\n" +
				                           "Please move other classes below the form class definition or move them to other files.");
			}
			
			return codeUnit;
		}