コード例 #1
0
        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));
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        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());
            }
        }
コード例 #5
0
        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;
        }
コード例 #6
0
        public PkgdefRegistryKeyPathSegment(IReadOnlyList <PkgdefToken> tokens)
        {
            PreCondition.AssertNotNullAndNotEmpty(tokens, nameof(tokens));
            PreCondition.AssertEqual(tokens[0].GetTokenType(), PkgdefTokenType.LeftSquareBracket, "tokens[0].GetTokenType()");

            this.tokens = tokens;
        }
コード例 #7
0
        public PkgdefRegistryKeySegment(IReadOnlyList <PkgdefSegment> segments)
        {
            PreCondition.AssertNotNullAndNotEmpty(segments, nameof(segments));
            PreCondition.AssertEqual(segments[0].GetSegmentType(), PkgdefSegmentType.RegistryKeyPath, "segments[0].GetSegmentType()");

            this.segments = segments;
        }
コード例 #8
0
        private PkgdefDocument(IReadOnlyList <PkgdefSegment> segments, IReadOnlyList <PkgdefIssue> issues)
        {
            PreCondition.AssertNotNull(segments, nameof(segments));
            PreCondition.AssertNotNull(issues, nameof(issues));

            this.segments = segments;
            this.issues   = issues;
        }
コード例 #9
0
 /// <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.");
     }
 }
コード例 #10
0
        /// <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();
            }
        }
コード例 #11
0
ファイル: PkgdefToken.cs プロジェクト: daschult/Pkgdef-CSharp
        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;
        }
コード例 #12
0
        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>();
        }
コード例 #13
0
        /// <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;
        }
コード例 #14
0
        /// <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);
        }
コード例 #15
0
        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));
        }
コード例 #16
0
        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> >();
        }
コード例 #17
0
        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()));
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        /// <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));
        }
コード例 #20
0
        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);
        }
コード例 #21
0
        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);
            }
        }
コード例 #22
0
#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());
        }
コード例 #23
0
        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);
        }
コード例 #24
0
        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);
        }
コード例 #25
0
        /// <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;
                }
            }
        }
コード例 #26
0
        /// <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)));
        }
コード例 #27
0
        public static string Quote(string value)
        {
            PreCondition.AssertNotNull(value, nameof(value));

            return($"\"{value}\"");
        }
コード例 #28
0
        public static PkgdefTokenizer Create(string text, Action <PkgdefIssue> onIssue)
        {
            PreCondition.AssertNotNull(text, "text");

            return(PkgdefTokenizer.Create(Iterator.Create(text), onIssue));
        }
コード例 #29
0
        /// <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());
        }
コード例 #30
0
        public static PkgdefTokenizer Create(Iterator <char> characters, Action <PkgdefIssue> onIssue)
        {
            PreCondition.AssertNotNull(characters, "characters");

            return(new PkgdefTokenizer(CurrentIndexIterator.Create(characters), onIssue));
        }