public static PkgdefTokenizer Create(int startIndex, string text, Action <PkgdefIssue> onIssue) { PreCondition.AssertGreaterThanOrEqualTo(startIndex, 0, nameof(startIndex)); PreCondition.AssertNotNull(text, "text"); return(PkgdefTokenizer.Create(startIndex, Iterator.Create(text), onIssue)); }
public PkgdefRegistryKeyDataItemSegment(IReadOnlyList <PkgdefToken> tokens) { PreCondition.AssertNotNullAndNotEmpty(tokens, nameof(tokens)); PreCondition.AssertOneOf(tokens.First().GetTokenType(), new[] { PkgdefTokenType.AtSign, PkgdefTokenType.DoubleQuote }, "tokens.First().GetTokenType()"); this.tokens = tokens; List <PkgdefToken> nameSegmentTokens = new List <PkgdefToken>() { tokens[0] }; if (tokens[0].GetTokenType() == PkgdefTokenType.DoubleQuote) { for (int i = 1; i < tokens.Count; i++) { nameSegmentTokens.Add(tokens[i]); if (tokens[i].GetTokenType() == PkgdefTokenType.DoubleQuote) { break; } } } this.nameSegment = new PkgdefRegistryKeyDataItemNameSegment(nameSegmentTokens); }
public static PkgdefTokenizer Create(int startIndex, Iterator <char> characters, Action <PkgdefIssue> onIssue) { PreCondition.AssertGreaterThanOrEqualTo(startIndex, 0, nameof(startIndex)); PreCondition.AssertNotNull(characters, "characters"); return(new PkgdefTokenizer(CurrentIndexIterator.Create(startIndex, characters), onIssue)); }
public static void AssertOneOf <T>(T value, IEnumerable <T> possibleValues, string valueName) { PreCondition.AssertNotNullAndNotEmpty(possibleValues, nameof(possibleValues)); if (!possibleValues.Contains(value)) { StringBuilder message = new StringBuilder(); message.Append($"{valueName} ({value}) must be "); int possibleValueCount = possibleValues.Count(); if (possibleValueCount == 1) { message.Append(Strings.Escape(possibleValues.First().ToString())); } else { message.Append("either "); if (possibleValueCount == 2) { message.Append($"{Strings.Escape(possibleValues.First().ToString())} "); } else { foreach (T possibleValue in possibleValues.Take(possibleValueCount - 1)) { message.Append($"{Strings.Escape(possibleValue.ToString())}, "); } } message.Append($"or {Strings.Escape(possibleValues.Last().ToString())}"); } message.Append('.'); throw new PreConditionException(message.ToString()); } }
public PkgdefRegistryKeyDataItemNameSegment(IReadOnlyList <PkgdefToken> tokens) { PreCondition.AssertNotNullAndNotEmpty(tokens, nameof(tokens)); PreCondition.AssertOneOf(tokens[0].GetTokenType(), new[] { PkgdefTokenType.AtSign, PkgdefTokenType.DoubleQuote }, "tokens[0].GetTokenType()"); this.tokens = tokens; }
public PkgdefRegistryKeyPathSegment(IReadOnlyList <PkgdefToken> tokens) { PreCondition.AssertNotNullAndNotEmpty(tokens, nameof(tokens)); PreCondition.AssertEqual(tokens[0].GetTokenType(), PkgdefTokenType.LeftSquareBracket, "tokens[0].GetTokenType()"); this.tokens = tokens; }
public PkgdefRegistryKeySegment(IReadOnlyList <PkgdefSegment> segments) { PreCondition.AssertNotNullAndNotEmpty(segments, nameof(segments)); PreCondition.AssertEqual(segments[0].GetSegmentType(), PkgdefSegmentType.RegistryKeyPath, "segments[0].GetSegmentType()"); this.segments = segments; }
private PkgdefDocument(IReadOnlyList <PkgdefSegment> segments, IReadOnlyList <PkgdefIssue> issues) { PreCondition.AssertNotNull(segments, nameof(segments)); PreCondition.AssertNotNull(issues, nameof(issues)); this.segments = segments; this.issues = issues; }
/// <summary> /// Assert that the provided value is not null and not empty. /// </summary> /// <param name="value">The value to check.</param> /// <param name="valueName">The name of the value to check.</param> public static void AssertNotNullAndNotEmpty <T>(IEnumerable <T> value, string valueName) { PreCondition.AssertNotNull(value, valueName); if (!value.Any()) { throw new PreConditionException($"{valueName} cannot be empty."); } }
/// <summary> /// Ensure that the Iterator has started. /// </summary> public static void EnsureHasStarted <T>(this Iterator <T> iterator) { PreCondition.AssertNotNull(iterator, nameof(iterator)); if (!iterator.HasStarted()) { iterator.Next(); } }
public PkgdefToken(int startIndex, string text, PkgdefTokenType tokenType) { PreCondition.AssertGreaterThanOrEqualTo(startIndex, 0, nameof(startIndex)); PreCondition.AssertNotNullAndNotEmpty(text, nameof(text)); this.startIndex = startIndex; this.text = text; this.tokenType = tokenType; }
private PkgdefTokenizer(CurrentIndexIterator <char> characters, Action <PkgdefIssue> onIssue) { PreCondition.AssertNotNull(characters, nameof(characters)); PreCondition.AssertNotNull(onIssue, nameof(onIssue)); this.characters = characters; this.onIssue = onIssue; this.tokenQueue = new Queue <PkgdefToken>(); }
/// <summary> /// Create a new PkgdefIssue object. /// </summary> /// <param name="startIndex">The character index that the issue starts on.</param> /// <param name="length">The number of characters that the issue spans over.</param> /// <param name="message">The message that describes the issue.</param> public PkgdefIssue(int startIndex, int length, string message) { PreCondition.AssertGreaterThanOrEqualTo(startIndex, 0, nameof(startIndex)); PreCondition.AssertGreaterThanOrEqualTo(length, 1, nameof(length)); PreCondition.AssertNotNullAndNotEmpty(message, nameof(message)); this.startIndex = startIndex; this.length = length; this.message = message; }
/// <summary> /// Take and return the current value and advance this iterator the next value. /// </summary> /// <returns>The taken current value.</returns> public static T TakeCurrent <T>(this Iterator <T> iterator) { PreCondition.AssertNotNull(iterator, nameof(iterator)); PreCondition.AssertTrue(iterator.HasCurrent(), "iterator.HasCurrent()"); T result = iterator.Current; iterator.Next(); return(result); }
internal static PkgdefRegistryKeyDataItemSegment ParseRegistryKeyDataItem(int startIndex, string text) { PreCondition.AssertGreaterThanOrEqualTo(startIndex, 0, nameof(startIndex)); PreCondition.AssertNotNullAndNotEmpty(text, nameof(text)); PreCondition.AssertOneOf(text[0], "@\"", "text[0]"); Action <PkgdefIssue> onIssue = PkgdefDocument.IgnoreIssue; PkgdefTokenizer tokenizer = PkgdefTokenizer.Create(startIndex, text, onIssue); tokenizer.Next(); return(PkgdefDocument.ParseRegistryKeyDataItem(tokenizer, onIssue)); }
internal PkgdefClassifier(IClassificationTypeRegistryService registry) { PreCondition.AssertNotNull(registry, nameof(registry)); this.substitutionStringClassificationType = registry.GetClassificationType(PkgdefClassifier.TypeNames.SubstitutionString); this.registryKeyRelativePathClassificationType = registry.GetClassificationType(PkgdefClassifier.TypeNames.RegistryKeyRelativePath); this.registryKeyDataItemNameClassificationType = registry.GetClassificationType(PkgdefClassifier.TypeNames.RegistryKeyDataItemName); this.registryKeyDataItemNumberValueClassificationType = registry.GetClassificationType(PkgdefClassifier.TypeNames.RegistryKeyDataItemNumberValue); this.registryKeyDataItemStringValueClassificationType = registry.GetClassificationType(PkgdefClassifier.TypeNames.RegistryKeyDataItemStringValue); this.commentClassificationType = registry.GetClassificationType(PkgdefClassifier.TypeNames.Comment); this.textSnapshotClassifications = new VersionedCache <ITextBuffer, int, IReadOnlyList <ClassificationSpan> >(); }
private void ReadDigits() { PreCondition.AssertTrue(this.characters.HasCurrent(), "this.characters.HasCurrent()"); PreCondition.AssertTrue(PkgdefTokenizer.IsDigit(this.characters.GetCurrent()), "PkgdefTokenizer.IsDigit(this.characters.GetCurrent())"); int startIndex = this.characters.GetCurrentIndex(); StringBuilder builder = new StringBuilder().Append(this.characters.TakeCurrent()); while (this.characters.HasCurrent() && PkgdefTokenizer.IsDigit(this.characters.GetCurrent())) { builder.Append(this.characters.TakeCurrent()); } this.tokenQueue.Enqueue(PkgdefToken.Digits(startIndex, builder.ToString())); }
public bool TryGet(SourceType source, VersionType version, out CacheValueType cachedValue) { PreCondition.AssertNotNull(source, nameof(source)); PreCondition.AssertNotNull(version, nameof(version)); bool result = false; cachedValue = default; if (this.cachedValues.TryGetValue(source, out Tuple <VersionType, CacheValueType> cachedValueWithVersion) && object.Equals(cachedValueWithVersion.Item1, version)) { result = true; cachedValue = cachedValueWithVersion.Item2; } return(result); }
/// <summary> /// Parse a PkgdefDocument from the provided characters. /// </summary> /// <param name="iterator">The characters to parse.</param> /// <returns>The parsed PkgdefDocument.</returns> public static PkgdefDocument Parse(Iterator <char> iterator) { PreCondition.AssertNotNull(iterator, nameof(iterator)); List <PkgdefIssue> issues = new List <PkgdefIssue>(); PkgdefTokenizer tokenizer = PkgdefTokenizer.Create(iterator, onIssue: issues.Add); tokenizer.EnsureHasStarted(); List <PkgdefSegment> segments = new List <PkgdefSegment>(); while (tokenizer.HasCurrent()) { segments.Add(PkgdefDocument.ParseSegment(tokenizer, onIssue: issues.Add)); } return(new PkgdefDocument(segments, issues)); }
private static PkgdefSegment ParseSegment(PkgdefTokenizer tokenizer, Action <PkgdefIssue> onIssue) { PreCondition.AssertNotNull(tokenizer, nameof(tokenizer)); PreCondition.AssertTrue(tokenizer.HasCurrent(), "tokenizer.HasCurrent()"); PreCondition.AssertNotNull(onIssue, nameof(onIssue)); PkgdefSegment result; switch (tokenizer.GetCurrent().GetTokenType()) { case PkgdefTokenType.Whitespace: result = PkgdefSegment.Whitespace(tokenizer.GetCurrent().GetStartIndex(), tokenizer.GetCurrent().GetText()); tokenizer.Next(); break; case PkgdefTokenType.NewLine: result = PkgdefSegment.NewLine(tokenizer.GetCurrent().GetStartIndex(), tokenizer.GetCurrent().GetText()); tokenizer.Next(); break; case PkgdefTokenType.ForwardSlash: result = PkgdefDocument.ParseLineComment(tokenizer, onIssue); break; case PkgdefTokenType.LeftSquareBracket: result = PkgdefDocument.ParseRegistryKeyPath(tokenizer, onIssue); break; case PkgdefTokenType.AtSign: case PkgdefTokenType.DoubleQuote: result = PkgdefDocument.ParseRegistryKeyDataItem(tokenizer, onIssue); break; default: result = PkgdefSegment.Unrecognized(tokenizer.GetCurrent().GetStartIndex(), tokenizer.GetCurrent().GetText()); tokenizer.Next(); break; } return(result); }
private void ReadWhitespace() { PreCondition.AssertTrue(this.characters.HasCurrent(), "this.characters.HasCurrent()"); PreCondition.AssertTrue(PkgdefTokenizer.IsWhitespaceCharacter(this.characters.GetCurrent()), "PkgdefTokenizer.IsWhitespaceCharacter(this.characters.GetCurrent())"); PkgdefToken newLineToken = null; int startIndex = this.characters.GetCurrentIndex(); StringBuilder builder = new StringBuilder(); while (this.characters.HasCurrent() && PkgdefTokenizer.IsWhitespaceCharacter(this.characters.GetCurrent())) { if (this.characters.GetCurrent() != '\r') { builder.Append(this.characters.TakeCurrent()); } else { int newLineStartIndex = this.characters.GetCurrentIndex(); if (this.characters.Next() && this.characters.GetCurrent() == '\n') { newLineToken = PkgdefToken.NewLine(newLineStartIndex, "\r\n"); this.characters.Next(); break; } else { builder.Append('\r'); } } } if (builder.Length > 0) { this.tokenQueue.Enqueue(PkgdefToken.Whitespace(startIndex, builder.ToString())); } if (newLineToken != null) { this.tokenQueue.Enqueue(newLineToken); } }
#pragma warning restore 67 public IList <ClassificationSpan> GetClassificationSpans(SnapshotSpan span) { PreCondition.AssertNotNull(span, nameof(span)); ITextSnapshot textSnapshot = span.Snapshot; ITextBuffer textBuffer = textSnapshot.TextBuffer; ITextVersion textVersion = textSnapshot.Version; int textVersionNumber = textVersion.VersionNumber; if (!this.textSnapshotClassifications.TryGet(textBuffer, textVersionNumber, out IReadOnlyList <ClassificationSpan> classificationSpans)) { PkgdefDocument parsedDocument = PkgdefDocument.Parse(textSnapshot.GetText()); List <ClassificationSpan> spans = new List <ClassificationSpan>(); foreach (PkgdefSegment segment in parsedDocument.GetSegments()) { switch (segment.GetSegmentType()) { case PkgdefSegmentType.LineComment: spans.Add(PkgdefClassifier.CreateClassificationSpan(textSnapshot, segment, this.commentClassificationType)); break; case PkgdefSegmentType.RegistryKeyPath: spans.Add(PkgdefClassifier.CreateClassificationSpan(textSnapshot, segment, this.registryKeyRelativePathClassificationType)); break; case PkgdefSegmentType.RegistryKeyDataItem: PkgdefRegistryKeyDataItemSegment registryKeyDataItemSegment = (PkgdefRegistryKeyDataItemSegment)segment; spans.Add(PkgdefClassifier.CreateClassificationSpan(textSnapshot, registryKeyDataItemSegment.GetNameSegment(), this.registryKeyDataItemNameClassificationType)); break; } } classificationSpans = spans; this.textSnapshotClassifications.Set(textBuffer, textVersionNumber, classificationSpans); } return(classificationSpans .Where((ClassificationSpan classificationSpan) => classificationSpan.Span.IntersectsWith(span.Span)) .ToList()); }
internal static PkgdefRegistryKeyPathSegment ParseRegistryKeyPath(PkgdefTokenizer tokenizer, Action <PkgdefIssue> onIssue) { PreCondition.AssertNotNull(tokenizer, nameof(tokenizer)); PreCondition.AssertTrue(tokenizer.HasCurrent(), "tokenizer.HasCurrent()"); PreCondition.AssertEqual(tokenizer.GetCurrent().GetTokenType(), PkgdefTokenType.LeftSquareBracket, "tokenizer.GetCurrent().GetTokenType()"); PreCondition.AssertNotNull(onIssue, nameof(onIssue)); List <PkgdefToken> tokens = new List <PkgdefToken>() { tokenizer.TakeCurrent() }; while (tokenizer.HasCurrent()) { PkgdefTokenType tokenType = tokenizer.GetCurrent().GetTokenType(); if (tokenType == PkgdefTokenType.NewLine) { break; } else { tokens.Add(tokenizer.TakeCurrent()); if (tokenType == PkgdefTokenType.RightSquareBracket) { break; } } } PkgdefRegistryKeyPathSegment result = new PkgdefRegistryKeyPathSegment(tokens); if (result.GetRightSquareBracket() == null) { onIssue(new PkgdefIssue(result.GetStartIndex(), result.GetLength(), "Missing registry key path right square bracket (']').")); } return(result); }
internal static PkgdefSegment ParseLineComment(PkgdefTokenizer tokenizer, Action <PkgdefIssue> onIssue) { PreCondition.AssertNotNull(tokenizer, nameof(tokenizer)); PreCondition.AssertTrue(tokenizer.HasCurrent(), "tokenizer.HasCurrent()"); PreCondition.AssertEqual(tokenizer.GetCurrent().GetTokenType(), PkgdefTokenType.ForwardSlash, "tokenizer.GetCurrent().GetTokenType()"); PreCondition.AssertNotNull(onIssue, nameof(onIssue)); PkgdefSegment result; int startIndex = tokenizer.TakeCurrent().GetStartIndex(); StringBuilder builder = new StringBuilder().Append('/'); if (!tokenizer.HasCurrent()) { onIssue(new PkgdefIssue(startIndex, 1, "Missing line-comment's second forward slash ('/').")); result = PkgdefSegment.Unrecognized(startIndex, builder.ToString()); } else if (tokenizer.GetCurrent().GetTokenType() != PkgdefTokenType.ForwardSlash) { onIssue.Invoke(new PkgdefIssue(startIndex + 1, 1, "Expected line-comment's second forward slash ('/').")); result = PkgdefSegment.Unrecognized(startIndex, builder.ToString()); } else { builder.Append('/'); tokenizer.Next(); while (tokenizer.HasCurrent() && tokenizer.GetCurrent().GetTokenType() != PkgdefTokenType.NewLine) { builder.Append(tokenizer.TakeCurrent().GetText()); } string text = builder.ToString(); result = PkgdefSegment.LineComment(startIndex, text); } return(result); }
/// <summary> /// Create a new Iterator that will iterate over the values in the provided IEnumerator. /// </summary> /// <param name="enumerator">The IEnumerator to iterate over.</param> internal EnumeratorIterator(IEnumerator <T> enumerator) { PreCondition.AssertNotNull(enumerator, nameof(enumerator)); this.enumerator = enumerator; try { this.hasCurrent = enumerator.Current != null; this.hasStarted = true; } catch (InvalidOperationException e) { // This exception is thrown when the IEnumerator hasn't started yet. this.hasCurrent = false; if (e.Message == "Enumeration has not started. Call MoveNext.") { this.hasStarted = false; } else { this.hasStarted = true; } } }
/// <summary> /// Parse a PkgdefDocument from the provided text. /// </summary> /// <param name="text">The text to parse.</param> /// <returns>The parsed PkgdefDocument.</returns> public static PkgdefDocument Parse(string text) { PreCondition.AssertNotNull(text, nameof(text)); return(PkgdefDocument.Parse(Iterator.Create(text))); }
public static string Quote(string value) { PreCondition.AssertNotNull(value, nameof(value)); return($"\"{value}\""); }
public static PkgdefTokenizer Create(string text, Action <PkgdefIssue> onIssue) { PreCondition.AssertNotNull(text, "text"); return(PkgdefTokenizer.Create(Iterator.Create(text), onIssue)); }
/// <summary> /// Get the index directly after (not contained by) this PkgdefSegment. /// </summary> public virtual int GetAfterEndIndex() { PreCondition.AssertGreaterThanOrEqualTo(this.GetLength(), 1, "this.GetLength()"); return(this.GetStartIndex() + this.GetLength()); }
public static PkgdefTokenizer Create(Iterator <char> characters, Action <PkgdefIssue> onIssue) { PreCondition.AssertNotNull(characters, "characters"); return(new PkgdefTokenizer(CurrentIndexIterator.Create(characters), onIssue)); }