internal void GetClassificationSpansWorker(SnapshotSpan span, IList <ClassificationSpan> classSpans, IList <XamlAnalyzer.LineState> stateSpans, XamlAnalyzer.LineState startState, out XamlAnalyzer.LineState endState) { classSpans.Clear(); if (stateSpans != null) { stateSpans.Clear(); } Scanner scanner = new Scanner((IScannerSource) new TextSnapshotScannerSource(span), new ScannerErrorHandler(this.HandleScannerError)); scanner.ScannerState = startState.ScannerState; ITextSnapshot snapshot = span.Snapshot; endState = startState; Token token; while (XamlAnalyzer.ClassificationScanner.GetNextToken(scanner, out token)) { XamlAnalyzer.ParseState newState; IClassificationType classType; XamlAnalyzer.Transition(token, scanner.WasWhitespaceSkipped, endState.ParseState, out newState, out classType); endState.ParseState = newState; endState.ScannerState = scanner.ScannerState; if (classType != XamlAnalyzer.ClassUnknown && classType != XamlAnalyzer.ClassNonTagContent) { classSpans.Add(new ClassificationSpan(new SnapshotSpan(snapshot, scanner.StartPos + span.Start, scanner.EndPos - scanner.StartPos), classType)); if (stateSpans != null) { stateSpans.Add(endState); } } } }
public SnapshotSpan GetMatchingEndTag(SnapshotSpan startTagSpan) { SnapshotSpan spanToTokenize = this.statefulClassifier.GetSpanToTokenize(startTagSpan); IList <ClassificationSpan> classificationSpans = this.statefulClassifier.GetClassificationSpans(spanToTokenize); int index = OrderedListExtensions.GenericBinarySearch <ClassificationSpan, int>(classificationSpans, startTagSpan.Start, (Func <int, ClassificationSpan, int>)((pos, span) => pos - span.Span.Start)); if (index < 0 || classificationSpans[index].ClassificationType != XamlAnalyzer.ClassStartTag) { return(new SnapshotSpan()); } int num1 = OrderedListExtensions.GenericBinarySearch <ClassificationSpan, int>(classificationSpans, startTagSpan.End, (Func <int, ClassificationSpan, int>)((pos, span) => pos - span.Span.Start)); if (num1 < 0) { num1 = ~num1; } ClassificationPosition startPosition = new ClassificationPosition() { CurrentLine = spanToTokenize, CurrentSpanList = classificationSpans, CurrentSpanIndex = num1 }; int num2 = 1; int start = -1; foreach (ClassificationPosition classificationPosition in this.statefulClassifier.ScanForward(startPosition)) { num2 += XamlAnalyzer.TagDepthDelta(true, classificationPosition.CurrentSpan.ClassificationType); if (num2 == 0) { start = classificationPosition.CurrentSpan.Span.Start; startPosition = classificationPosition; break; } } if (start >= 0) { foreach (ClassificationPosition classificationPosition in this.statefulClassifier.ScanForward(startPosition)) { if (classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassEndTag) { return(new SnapshotSpan(classificationPosition.Snapshot, new Span(start, classificationPosition.CurrentSpan.Span.End - start))); } } } return(new SnapshotSpan()); }
internal XamlNameDecomposition GetPreviousTagName(SnapshotPoint position) { SnapshotSpan spanToTokenize = this.statefulClassifier.GetSpanToTokenize(position); XamlAnalyzer.LineState state1 = this.statefulClassifier.GetState(spanToTokenize.Snapshot, spanToTokenize.Start); IList <ClassificationSpan> list = (IList <ClassificationSpan>) new List <ClassificationSpan>(); IList <XamlAnalyzer.LineState> stateSpans = (IList <XamlAnalyzer.LineState>) new List <XamlAnalyzer.LineState>(); XamlAnalyzer.LineState endState; this.classificationScanner.GetClassificationSpansWorker(spanToTokenize, list, stateSpans, state1, out endState); int num1 = OrderedListExtensions.GenericBinarySearch <ClassificationSpan, SnapshotPoint>(list, position, (Func <SnapshotPoint, ClassificationSpan, int>)((pos, span) => pos.Position - span.Span.Start)); if (num1 < 0) { num1 = ~num1; } int index = num1 - 1; XamlAnalyzer.ParseState state2; if (index < 0) { state2 = state1.ParseState; } else { state2 = stateSpans[index].ParseState; switch (state2) { case XamlAnalyzer.ParseState.EmptyTagEnd: case XamlAnalyzer.ParseState.TagEnd: if (list[index].Span.IntersectsWith(new Span(position.Position, 0))) { state2 = index != 0 ? stateSpans[index - 1].ParseState : stateSpans[index].ParseState; break; } break; } } int num2 = -1; if (XamlAnalyzer.IsInsideTag(state2)) { foreach (ClassificationPosition classificationPosition in this.statefulClassifier.ScanBackward(new ClassificationPosition() { CurrentLine = spanToTokenize, CurrentSpanList = list, CurrentSpanIndex = index })) { if (classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassStartTag) { num2 = classificationPosition.CurrentSpan.Span.Start; break; } if (classificationPosition.CurrentSpan.ClassificationType != XamlAnalyzer.ClassStartClosingTag) { if (classificationPosition.CurrentSpan.ClassificationType != XamlAnalyzer.ClassEndEmptyTag) { if (classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassEndTag) { break; } } else { break; } } else { break; } } } if (num2 == -1) { return((XamlNameDecomposition)null); } return(this.GetNameAtPosition(new SnapshotPoint(position.Snapshot, num2 + 1))); }
private SnapshotSpan GetContainingTag(SnapshotPoint position, bool shouldReturnCloseTagSpan, out bool isInCloseTag, bool returnEmptySpanOnContent) { isInCloseTag = false; SnapshotSpan spanToTokenize = this.statefulClassifier.GetSpanToTokenize(position); XamlAnalyzer.LineState state1 = this.statefulClassifier.GetState(spanToTokenize.Snapshot, spanToTokenize.Start); IList <ClassificationSpan> list1 = (IList <ClassificationSpan>) new List <ClassificationSpan>(); IList <XamlAnalyzer.LineState> list2 = (IList <XamlAnalyzer.LineState>) new List <XamlAnalyzer.LineState>(); XamlAnalyzer.LineState endState; this.classificationScanner.GetClassificationSpansWorker(spanToTokenize, list1, list2, state1, out endState); int num1 = OrderedListExtensions.GenericBinarySearch <ClassificationSpan, SnapshotPoint>(list1, position, (Func <SnapshotPoint, ClassificationSpan, int>)((pos, span) => pos.Position - span.Span.Start)); if (num1 < 0) { num1 = ~num1; } int startSpanIndex = num1 - 1; XamlAnalyzer.ParseState state2 = startSpanIndex >= 0 ? list2[startSpanIndex].ParseState : state1.ParseState; if (XamlAnalyzer.IsInsideClosingTag(list2, startSpanIndex)) { isInCloseTag = true; ClassificationPosition startPosition = new ClassificationPosition() { CurrentLine = spanToTokenize, CurrentSpanList = list1, CurrentSpanIndex = startSpanIndex }; int currentSpanIndex = startPosition.CurrentSpanIndex; if (startSpanIndex >= 0 && startPosition.CurrentSpan.ClassificationType != XamlAnalyzer.ClassStartClosingTag) { foreach (ClassificationPosition classificationPosition in this.statefulClassifier.ScanBackward(startPosition)) { if (classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassStartClosingTag) { startPosition = classificationPosition; currentSpanIndex = classificationPosition.CurrentSpanIndex; break; } } } if (shouldReturnCloseTagSpan) { int start = startPosition.CurrentSpanList[Math.Max(0, currentSpanIndex)].Span.Start; int end = startPosition.CurrentSpanList[Math.Max(0, currentSpanIndex)].Span.End; for (int index = currentSpanIndex + 1; index < startPosition.CurrentSpanList.Count && XamlAnalyzer.IsTokenValidInCloseTag(startPosition.CurrentSpanList[index].ClassificationType); ++index) { end = startPosition.CurrentSpanList[index].Span.End; } return(new SnapshotSpan(startPosition.Snapshot, start, end - start)); } int num2 = 1; foreach (ClassificationPosition classificationPosition in this.statefulClassifier.ScanBackward(startPosition)) { num2 += XamlAnalyzer.TagDepthDelta(false, classificationPosition.CurrentSpan.ClassificationType); if (num2 == 0) { startPosition = classificationPosition; break; } } if (num2 != 0) { return(new SnapshotSpan()); } int start1 = startPosition.CurrentSpan.Span.Start; foreach (ClassificationPosition classificationPosition in this.statefulClassifier.ScanForward(startPosition)) { if (classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassEndTag || classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassEndEmptyTag) { return(new SnapshotSpan(classificationPosition.Snapshot, new Span(start1, classificationPosition.CurrentSpan.Span.End - start1))); } if (classificationPosition.CurrentSpan.Span != startPosition.CurrentSpan.Span && (classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassStartTag || classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassStartClosingTag)) { return(new SnapshotSpan(classificationPosition.Snapshot, new Span(start1, classificationPosition.CurrentSpan.Span.Start - start1))); } } } else if (XamlAnalyzer.IsInsideTag(state2)) { ClassificationPosition startPosition = new ClassificationPosition() { CurrentLine = spanToTokenize, CurrentSpanList = list1, CurrentSpanIndex = startSpanIndex }; int start = -1; if (startPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassStartTag) { start = startPosition.CurrentSpan.Span.Start; } else { foreach (ClassificationPosition classificationPosition in this.statefulClassifier.ScanBackward(startPosition)) { if (classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassStartTag) { start = classificationPosition.CurrentSpan.Span.Start; break; } } } int num2 = startPosition.Snapshot.Length; foreach (ClassificationPosition classificationPosition in this.statefulClassifier.ScanForward(startPosition)) { if (classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassEndEmptyTag || classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassEndTag) { num2 = classificationPosition.CurrentSpan.Span.End; break; } if (classificationPosition.CurrentSpan.Span != startPosition.CurrentSpan.Span && (classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassStartTag || classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassStartClosingTag)) { num2 = classificationPosition.CurrentSpan.Span.Start; break; } } if (start >= 0 && num2 > start) { return(new SnapshotSpan(startPosition.Snapshot, new Span(start, num2 - start))); } } else { if (returnEmptySpanOnContent) { return(new SnapshotSpan()); } int num2 = state2 == XamlAnalyzer.ParseState.EmptyTagEnd ? 2 : 1; ClassificationPosition startPosition = new ClassificationPosition() { CurrentLine = spanToTokenize, CurrentSpanList = list1, CurrentSpanIndex = startSpanIndex }; foreach (ClassificationPosition classificationPosition in this.statefulClassifier.ScanBackward(startPosition)) { num2 += XamlAnalyzer.TagDepthDelta(false, classificationPosition.CurrentSpan.ClassificationType); if (num2 == 0) { startPosition = classificationPosition; break; } } if (num2 != 0) { return(new SnapshotSpan()); } int start = startPosition.CurrentSpan.Span.Start; foreach (ClassificationPosition classificationPosition in this.statefulClassifier.ScanForward(startPosition)) { if (classificationPosition.CurrentSpan.ClassificationType == XamlAnalyzer.ClassEndTag) { return(new SnapshotSpan(classificationPosition.Snapshot, new Span(start, classificationPosition.CurrentSpan.Span.End - start))); } } } return(new SnapshotSpan()); }
public XamlNameDecomposition GetNameAtPosition(SnapshotPoint position) { IList <ClassificationSpan> classificationSpans = this.statefulClassifier.GetClassificationSpans(position.GetContainingLine().ExtentIncludingLineBreak); int index = OrderedListExtensions.GenericBinarySearch <ClassificationSpan, int>(classificationSpans, position.Position, (Func <int, ClassificationSpan, int>)((pos, span) => pos - span.Span.Start)); if (index < 0) { index = Math.Max(0, ~index - 1); } if (this.CursorIsInSpanGap(classificationSpans, index, position.Position)) { return((XamlNameDecomposition)null); } while (index > 0 && (classificationSpans[index].Span.Start == classificationSpans[index - 1].Span.End && XamlAnalyzer.IsPartOfName(classificationSpans[index - 1].ClassificationType))) { --index; } if (classificationSpans[index].ClassificationType == XamlAnalyzer.ClassTagNameIdentifier || classificationSpans[index].ClassificationType == XamlAnalyzer.ClassAttrNameIdentifier) { return(new XamlNameDecomposition(classificationSpans, index)); } return((XamlNameDecomposition)null); }
internal static bool Transition(Token token, bool wasWhitespaceSkipped, XamlAnalyzer.ParseState currentState, out XamlAnalyzer.ParseState newState, out IClassificationType classType) { if (wasWhitespaceSkipped && (currentState == XamlAnalyzer.ParseState.TagNamePart || currentState == XamlAnalyzer.ParseState.TagPrefixColon)) { currentState = XamlAnalyzer.ParseState.AfterTagName; } switch (token) { case Token.Assign: newState = XamlAnalyzer.ParseState.AttrEquals; classType = XamlAnalyzer.ClassAttrEquals; return(true); case Token.Colon: newState = currentState != XamlAnalyzer.ParseState.TagNamePart ? (currentState != XamlAnalyzer.ParseState.ClosingTagNamePart ? XamlAnalyzer.ParseState.AttrPrefixColon : XamlAnalyzer.ParseState.ClosingTagPrefixColon) : XamlAnalyzer.ParseState.TagPrefixColon; classType = XamlAnalyzer.ClassNameColon; return(true); case Token.Comment: newState = currentState; classType = XamlAnalyzer.ClassComment; return(true); case Token.EndOfLine: newState = currentState == XamlAnalyzer.ParseState.TagNamePart || currentState == XamlAnalyzer.ParseState.TagPrefixColon ? XamlAnalyzer.ParseState.AfterTagName : currentState; classType = XamlAnalyzer.ClassUnknown; return(false); case Token.EndOfTag: newState = XamlAnalyzer.ParseState.TagEnd; classType = XamlAnalyzer.ClassEndTag; return(true); case Token.EndOfSimpleTag: newState = XamlAnalyzer.ParseState.EmptyTagEnd; classType = XamlAnalyzer.ClassEndEmptyTag; return(true); case Token.Identifier: if (XamlAnalyzer.IsAfterTagName(currentState) || currentState == XamlAnalyzer.ParseState.TagNamePart) { newState = XamlAnalyzer.ParseState.AttrNamePart; classType = XamlAnalyzer.ClassAttrNameIdentifier; } else if (XamlAnalyzer.IsInsideTag(currentState)) { bool flag = false; if ((currentState & XamlAnalyzer.ParseState.IsClosingTag) == XamlAnalyzer.ParseState.IsClosingTag) { flag = true; } newState = flag ? XamlAnalyzer.ParseState.ClosingTagNamePart : XamlAnalyzer.ParseState.TagNamePart; classType = XamlAnalyzer.ClassTagNameIdentifier; } else { newState = currentState; classType = XamlAnalyzer.ClassUnknown; } return(true); case Token.LiteralContentString: newState = XamlAnalyzer.ParseState.Content; classType = XamlAnalyzer.ClassNonTagContent; return(true); case Token.StartOfClosingTag: newState = XamlAnalyzer.ParseState.ClosingTagStart; classType = XamlAnalyzer.ClassStartClosingTag; return(true); case Token.StartOfTag: newState = XamlAnalyzer.ParseState.TagStart; classType = XamlAnalyzer.ClassStartTag; return(true); case Token.StringLiteral: newState = XamlAnalyzer.ParseState.AfterTagName; classType = XamlAnalyzer.ClassAttrValue; return(true); default: newState = currentState; classType = XamlAnalyzer.ClassUnknown; return(false); } }