private void addStartRegion( string lineContent, int regionStart, int lineNumber, int regionStartHoverText, ref PartialRegion currentRegion, IList <Region> newRegions) { //AsmDudeToolsStatic.Output("INFO: CodeFoldingTagger: addStartRegion"); int currentLevel = (currentRegion != null) ? currentRegion.Level : 1; int newLevel = currentLevel + 1; //levels are the same and we have an existing region; //end the current region and start the next if ((currentLevel == newLevel) && (currentRegion != null)) { newRegions.Add(new Region() { Level = currentRegion.Level, StartLine = currentRegion.StartLine, StartOffset = currentRegion.StartOffset, StartOffsetHoverText = regionStartHoverText, EndLine = lineNumber }); currentRegion = new PartialRegion() { Level = newLevel, StartLine = lineNumber, StartOffset = regionStart, StartOffsetHoverText = regionStartHoverText, PartialParent = currentRegion.PartialParent }; } //this is a new (sub)region else { currentRegion = new PartialRegion() { Level = newLevel, StartLine = lineNumber, StartOffset = regionStart, StartOffsetHoverText = regionStartHoverText, PartialParent = currentRegion }; } }
private void addEndRegion( string lineContent, int regionEnd, int lineNumber, ref PartialRegion currentRegion, IList <Region> newRegions) { //AsmDudeToolsStatic.Output("INFO: CodeFoldingTagger: addEndRegion: lineContent="+lineContent +"; regionEnd="+regionEnd +"; lineNumber="+lineNumber); if (currentRegion != null) { newRegions.Add(new Region() { Level = currentRegion.Level, StartLine = currentRegion.StartLine, StartOffset = currentRegion.StartOffset, StartOffsetHoverText = currentRegion.StartOffsetHoverText, EndLine = lineNumber }); currentRegion = currentRegion.PartialParent; } }
private void Parse() { if (!this._enabled) { return; } lock (this._updateLock) { DateTime time1 = DateTime.Now; ITextSnapshot newSnapshot = this._buffer.CurrentSnapshot; IList <Region> newRegions = new List <Region>(); // keep the current (deepest) partial region, which will have // references to any parent partial regions. PartialRegion currentRegion = null; IEnumerator <ITextSnapshotLine> enumerator = newSnapshot.Lines.GetEnumerator(); ITextSnapshotLine line = null; bool hasNext = enumerator.MoveNext(); bool already_advanced = true; if (hasNext) { line = enumerator.Current; } while (hasNext) { already_advanced = false; #region Parse Line if (line.Length > 0) { string lineContent = line.GetText(); int lineNumber = line.LineNumber; (int regionStart, int regionStartHoverText) = this.Is_Start_Keyword(lineContent, lineNumber); if (regionStart != -1) { this.Add_Start_Region(lineContent, regionStart, lineNumber, regionStartHoverText, ref currentRegion, newRegions); } else { int regionEnd = this.Is_End_Keyword(lineContent, lineNumber); if (regionEnd != -1) { this.Add_End_Region(lineContent, regionEnd, lineNumber, ref currentRegion, newRegions); } else { #region Search for multi-line Remark if (AsmSourceTools.IsRemarkOnly(lineContent)) { int lineNumber2 = -1; string lineContent2 = null; while (enumerator.MoveNext()) { line = enumerator.Current; string lineContent3 = line.GetText(); if (AsmSourceTools.IsRemarkOnly(lineContent3) && (this.Is_Start_Directive_Keyword(lineContent3).StartPos == -1) && (this.Is_End_Directive_Keyword(lineContent3) == -1)) { lineNumber2 = line.LineNumber; lineContent2 = lineContent3; already_advanced = false; } else { already_advanced = true; break; } } if (lineNumber2 != -1) { int regionStartPos = AsmSourceTools.GetRemarkCharPosition(lineContent); this.Add_Start_Region(lineContent, regionStartPos, lineNumber, regionStartPos, ref currentRegion, newRegions); //this.updateChangedSpans(newSnapshot, newRegions); this.Add_End_Region(lineContent2, 0, lineNumber2, ref currentRegion, newRegions); } } #endregion } } } #endregion Parse Line #region Update Changed Spans this.Update_Changed_Spans(newSnapshot, newRegions); #endregion #region Advance to next line if (!already_advanced) { hasNext = enumerator.MoveNext(); if (hasNext) { line = enumerator.Current; } } #endregion } AsmDudeToolsStatic.Print_Speed_Warning(time1, "CodeFoldingTagger"); double elapsedSec = (double)(DateTime.Now.Ticks - time1.Ticks) / 10000000; if (elapsedSec > AsmDudePackage.SlowShutdownThresholdSec) { # if DEBUG AsmDudeToolsStatic.Output_WARNING("CodeFoldingTagger: Parse: disabled CodeFolding had I been in Release mode"); # else this.Disable(); # endif }
private void ReParse() { //Debug.WriteLine("INFO:OutliningTagger:ReParse: entering"); ITextSnapshot newSnapshot = _buffer.CurrentSnapshot; List <Region> newRegions = new List <Region>(); //keep the current (deepest) partial region, which will have // references to any parent partial regions. PartialRegion currentRegion = null; foreach (var line in newSnapshot.Lines) { int regionStart = -1; string text = line.GetText(); //lines that contain a "[" denote the start of a new region. if ((regionStart = text.IndexOf(startHide, StringComparison.Ordinal)) != -1) { int currentLevel = (currentRegion != null) ? currentRegion.Level : 1; int newLevel; if (!TryGetLevel(text, regionStart, out newLevel)) { newLevel = currentLevel + 1; } //levels are the same and we have an existing region; //end the current region and start the next if (currentLevel == newLevel && currentRegion != null) { newRegions.Add(new Region() { Level = currentRegion.Level, StartLine = currentRegion.StartLine, StartOffset = currentRegion.StartOffset, EndLine = line.LineNumber }); currentRegion = new PartialRegion() { Level = newLevel, StartLine = line.LineNumber, StartOffset = regionStart, PartialParent = currentRegion.PartialParent }; } //this is a new (sub)region else { currentRegion = new PartialRegion() { Level = newLevel, StartLine = line.LineNumber, StartOffset = regionStart, PartialParent = currentRegion }; } } //lines that contain "]" denote the end of a region else if ((regionStart = text.IndexOf(endHide, StringComparison.Ordinal)) != -1) { int currentLevel = (currentRegion != null) ? currentRegion.Level : 1; int closingLevel; if (!TryGetLevel(text, regionStart, out closingLevel)) { closingLevel = currentLevel; } //the regions match if (currentRegion != null && currentLevel == closingLevel) { newRegions.Add(new Region() { Level = currentLevel, StartLine = currentRegion.StartLine, StartOffset = currentRegion.StartOffset, EndLine = line.LineNumber }); currentRegion = currentRegion.PartialParent; } } } //determine the changed span, and send a changed event with the new spans List <Span> oldSpans = new List <Span>(this._regions.Select(r => AsSnapshotSpan(r, this._snapshot) .TranslateTo(newSnapshot, SpanTrackingMode.EdgeExclusive) .Span)); List <Span> newSpans = new List <Span>(newRegions.Select(r => AsSnapshotSpan(r, newSnapshot).Span)); NormalizedSpanCollection oldSpanCollection = new NormalizedSpanCollection(oldSpans); NormalizedSpanCollection newSpanCollection = new NormalizedSpanCollection(newSpans); //the changed regions are regions that appear in one set or the other, but not both. NormalizedSpanCollection removed = NormalizedSpanCollection.Difference(oldSpanCollection, newSpanCollection); int changeStart = int.MaxValue; int changeEnd = -1; if (removed.Count > 0) { changeStart = removed[0].Start; changeEnd = removed[removed.Count - 1].End; } if (newSpans.Count > 0) { changeStart = Math.Min(changeStart, newSpans[0].Start); changeEnd = Math.Max(changeEnd, newSpans[newSpans.Count - 1].End); } this._snapshot = newSnapshot; this._regions = newRegions; if (changeStart <= changeEnd) { ITextSnapshot snap = this._snapshot; if (this.TagsChanged != null) { this.TagsChanged(this, new SnapshotSpanEventArgs( new SnapshotSpan(this._snapshot, Span.FromBounds(changeStart, changeEnd)))); } } //Debug.WriteLine("INFO:OutliningTagger:ReParse: leaving"); }
private void parse(object threadContext) { if (!this._enabled) { return; } this._waiting = true; Thread.Sleep(AsmDudePackage.msSleepBeforeAsyncExecution); this._busy = true; this._waiting = false; #region Payload lock (_updateLock) { DateTime time1 = DateTime.Now; ITextSnapshot newSnapshot = _buffer.CurrentSnapshot; IList <Region> newRegions = new List <Region>(); // keep the current (deepest) partial region, which will have // references to any parent partial regions. PartialRegion currentRegion = null; IEnumerator <ITextSnapshotLine> enumerator = newSnapshot.Lines.GetEnumerator(); ITextSnapshotLine line = null; bool hasNext = enumerator.MoveNext(); bool already_advanced = true; if (hasNext) { line = enumerator.Current; } while (hasNext) { already_advanced = false; #region Parse Line if (line.Length > 0) { string lineContent = line.GetText(); int lineNumber = line.LineNumber; Tuple <int, int> tup = this.isStartKeyword(lineContent, lineNumber); int regionStart = tup.Item1; int regionStartHoverText = tup.Item2; if (regionStart != -1) { this.addStartRegion(lineContent, regionStart, lineNumber, regionStartHoverText, ref currentRegion, newRegions); } else { int regionEnd = this.isEndKeyword(lineContent, lineNumber); if (regionEnd != -1) { this.addEndRegion(lineContent, regionEnd, lineNumber, ref currentRegion, newRegions); } else { #region Search for multi-line Remark if (AsmSourceTools.isRemarkOnly(lineContent)) { int lineNumber2 = -1; string lineContent2 = null; while (enumerator.MoveNext()) { line = enumerator.Current; string lineContent3 = line.GetText(); if (AsmSourceTools.isRemarkOnly(lineContent3) && (this.isStartDirectiveKeyword(lineContent3).Item1 == -1) && (this.isEndDirectiveKeyword(lineContent3) == -1)) { lineNumber2 = line.LineNumber; lineContent2 = lineContent3; already_advanced = false; } else { already_advanced = true; break; } } if (lineNumber2 != -1) { int regionStartPos = AsmSourceTools.getRemarkCharPosition(lineContent); this.addStartRegion(lineContent, regionStartPos, lineNumber, regionStartPos, ref currentRegion, newRegions); //this.updateChangedSpans(newSnapshot, newRegions); this.addEndRegion(lineContent2, 0, lineNumber2, ref currentRegion, newRegions); } } #endregion } } } #endregion Parse Line #region Update Changed Spans this.updateChangedSpans(newSnapshot, newRegions); #endregion #region Advance to next line if (!already_advanced) { hasNext = enumerator.MoveNext(); if (hasNext) { line = enumerator.Current; } } #endregion } AsmDudeToolsStatic.printSpeedWarning(time1, "CodeFoldingTagger"); double elapsedSec = (double)(DateTime.Now.Ticks - time1.Ticks) / 10000000; if (elapsedSec > AsmDudePackage.slowShutdownThresholdSec) { this.disable(); } } #endregion Payload this._busy = false; if (this._scheduled) { this._scheduled = false; this.parse_Delayed(); } }