public TrackedSegment(DocumentScript script, int originalStart, int originalEnd) { this.script = script; this.originalVersion = script.currentDocument.Version; this.originalStart = originalStart; this.originalEnd = originalEnd; }
/// <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; }
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; }
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(); } }
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; }
public int MoveOffsetTo(ITextSourceVersion other, int oldOffset, AnchorMovementType movement) { if (this != other) { throw new ArgumentException("other belongs to different document"); } return(oldOffset); }
public IEnumerable <TextChangeEventArgs> GetChangesTo(ITextSourceVersion other) { if (this != other) { throw new ArgumentException("other belongs to different document"); } return(EmptyList <TextChangeEventArgs> .Instance); }
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; }
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; }
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; }
/// <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; }
/// <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(); } } }
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; }
internal void SetEditor(TextEditor editor) { if (editor == null) { throw new ArgumentNullException(nameof(editor)); } this.editor = editor; this.version = editor.Version; OnEditorSet(); }
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; }
public bool BelongsToSameDocumentAs(ITextSourceVersion other) { if (other == null) { throw new ArgumentNullException("other"); } Version o = other as Version; return(o != null && provider == o.provider); }
/// <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); }
/// <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)); }
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; }
/// <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; }
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; }
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; }
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); } }
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; }
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; }
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; }
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; }
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)); }
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; }
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; }