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 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)); }
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."); } }
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> /// 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(); } }
/// <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 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> >(); }
/// <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)); }
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); }
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); }
#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); }
/// <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; } } }
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> /// Get the current value in this iterator. /// </summary> /// <typeparam name="T">The type of values iterate over by the iterator.</typeparam> /// <param name="iterator">The iterator to get the current value of.</param> /// <returns>The current value of this iterator.</returns> public static T GetCurrent <T>(this Iterator <T> iterator) { PreCondition.AssertNotNull(iterator, nameof(iterator)); return(iterator.Current); }
public static PkgdefTokenizer Create(Iterator <char> characters, Action <PkgdefIssue> onIssue) { PreCondition.AssertNotNull(characters, "characters"); return(new PkgdefTokenizer(CurrentIndexIterator.Create(characters), onIssue)); }
/// <summary> /// Move to the next value in this Iterator. /// </summary> /// <returns>Whether or not a next value was found.</returns> public static bool Next <T>(this Iterator <T> iterator) { PreCondition.AssertNotNull(iterator, nameof(iterator)); return(iterator.MoveNext()); }
public static PkgdefTokenizer Create(string text, Action <PkgdefIssue> onIssue) { PreCondition.AssertNotNull(text, "text"); return(PkgdefTokenizer.Create(Iterator.Create(text), onIssue)); }
/// <summary> /// Create a new CurrentIndexIterator that will iterate over the values in the provided IEnumerable. /// </summary> /// <param name="enumerable">The IEnumerable to iterate over.</param> /// <returns>A new CurrentIndexIterator that will iterate over the values in the provided IEnumerable.</returns> public static CurrentIndexIterator <T> Create <T>(IEnumerable <T> enumerable) { PreCondition.AssertNotNull(enumerable, nameof(enumerable)); return(CurrentIndexIterator.Create(Iterator.Create(enumerable))); }
public static string Quote(string value) { PreCondition.AssertNotNull(value, nameof(value)); return($"\"{value}\""); }
internal static PkgdefRegistryKeyDataItemSegment ParseRegistryKeyDataItem(PkgdefTokenizer tokenizer, Action <PkgdefIssue> onIssue) { PreCondition.AssertNotNull(tokenizer, nameof(tokenizer)); PreCondition.AssertTrue(tokenizer.HasCurrent(), "tokenizer.HasCurrent()"); PreCondition.AssertOneOf(tokenizer.GetCurrent().GetTokenType(), new[] { PkgdefTokenType.AtSign, PkgdefTokenType.DoubleQuote }, "tokenizer.GetCurrent().GetTokenType()"); PreCondition.AssertNotNull(onIssue, nameof(onIssue)); PkgdefToken registryKeyDataItemNameFirstToken = tokenizer.TakeCurrent(); List <PkgdefToken> tokens = new List <PkgdefToken>() { registryKeyDataItemNameFirstToken }; bool dataItemDone = false; if (registryKeyDataItemNameFirstToken.GetTokenType() == PkgdefTokenType.DoubleQuote) { if (!tokenizer.HasCurrent()) { onIssue(new PkgdefIssue(registryKeyDataItemNameFirstToken.GetStartIndex(), registryKeyDataItemNameFirstToken.GetLength(), "Missing registry key data item name closing double-quote ('\"').")); dataItemDone = true; } else { while (tokenizer.HasCurrent()) { PkgdefTokenType tokenType = tokenizer.GetCurrent().GetTokenType(); if (tokenType == PkgdefTokenType.NewLine) { onIssue(new PkgdefIssue(PkgdefToken.GetStartIndex(tokens), PkgdefToken.GetLength(tokens), "Missing registry key data item name closing double-quote ('\"').")); dataItemDone = true; break; } else { PkgdefToken token = tokenizer.TakeCurrent(); tokens.Add(token); if (token.GetTokenType() == PkgdefTokenType.DoubleQuote) { break; } } } } } if (!dataItemDone) { if (!tokenizer.HasCurrent()) { onIssue(new PkgdefIssue(PkgdefToken.GetStartIndex(tokens), PkgdefToken.GetLength(tokens), "Missing registry key data item equals sign ('=').")); dataItemDone = true; } else { while (tokenizer.HasCurrent()) { PkgdefTokenType tokenType = tokenizer.GetCurrent().GetTokenType(); if (tokenType == PkgdefTokenType.NewLine) { onIssue(new PkgdefIssue(PkgdefToken.GetStartIndex(tokens), PkgdefToken.GetLength(tokens), "Missing registry key data item equals sign ('=').")); dataItemDone = true; break; } else { PkgdefToken token = tokenizer.TakeCurrent(); tokens.Add(token); if (token.GetTokenType() == PkgdefTokenType.EqualsSign) { break; } else if (token.GetTokenType() != PkgdefTokenType.Whitespace) { onIssue(new PkgdefIssue(token.GetStartIndex(), token.GetLength(), "Expected registry key data item equals sign ('=').")); } } } } } if (!dataItemDone) { if (!tokenizer.HasCurrent()) { onIssue(new PkgdefIssue(PkgdefToken.GetStartIndex(tokens), PkgdefToken.GetLength(tokens), "Missing registry key data item value.")); } else { int dataItemValueTokenCount = 0; while (tokenizer.HasCurrent()) { PkgdefTokenType tokenType = tokenizer.GetCurrent().GetTokenType(); if (tokenType == PkgdefTokenType.NewLine) { if (dataItemValueTokenCount == 0) { onIssue(new PkgdefIssue(PkgdefToken.GetStartIndex(tokens), PkgdefToken.GetLength(tokens), "Missing registry key data item value.")); } break; } else { PkgdefToken token = tokenizer.TakeCurrent(); tokens.Add(token); if (token.GetTokenType() != PkgdefTokenType.Whitespace) { dataItemValueTokenCount++; } } } } } return(new PkgdefRegistryKeyDataItemSegment(tokens)); }
/// <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))); }
/// <summary> /// Create a new Iterator that will iterate over the values in the provided IEnumerable. /// </summary> /// <param name="enumerable">The IEnumerable to iterate over.</param> /// <returns>A new Iterator that will iterate over the values in the provided IEnumerable.</returns> public static Iterator <T> Create <T>(IEnumerable <T> enumerable) { PreCondition.AssertNotNull(enumerable, nameof(enumerable)); return(Iterator.Create(enumerable.GetEnumerator())); }