예제 #1
0
        public static Optional <MatchResult <NamedTypeDetails> > NamedType(IReadStringContent reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var name = Optional <IdentifierDetails> .Missing;
            var genericTypeParameters = Optional <ImmutableList <GenericTypeParameterDetails> > .Missing;
            var readerAfterValue      = reader
                                        .StartMatching()
                                        .Then(Identifier, value => name = value)
                                        .ThenOptionally(Whitespace)
                                        .If(Match('<')).Then(GenericTypeParameters, value => genericTypeParameters = value);

            if (!readerAfterValue.IsDefined)
            {
                return(null);
            }
            if (genericTypeParameters.IsDefined && !genericTypeParameters.Value.Any())
            {
                throw new ArgumentException($"Invalid named type content starting at {reader.Index} - has generic type param opening bracket but zero type params present");
            }

            return(MatchResult.New(
                       new NamedTypeDetails(
                           name.Value,
                           genericTypeParameters.GetValueOrDefault(ImmutableList <GenericTypeParameterDetails> .Empty)
                           ),
                       readerAfterValue.Value
                       ));
        }
        private static bool PositionIsOverWhitespace(IReadStringContent reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            return((reader.Current != null) && char.IsWhiteSpace(reader.Current.Value));
        }
        public static Optional <IReadStringContent> StartMatching(this IReadStringContent reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            return(Optional.For(reader));
        }
예제 #4
0
        private static SourceRangeDetails GetSourceRangeFromReaders(IReadStringContent readerStart, IReadStringContent readerAfter)
        {
            if (readerAfter == null)
            {
                throw new ArgumentNullException(nameof(readerAfter));
            }

            return(new SourceRangeDetails(readerStart.Index, readerAfter.Index - readerStart.Index));
        }
            public CharacterAndNextReader(char character, IReadStringContent nextReader)
            {
                if (nextReader == null)
                {
                    throw new ArgumentNullException(nameof(nextReader));
                }

                Character  = character;
                NextReader = nextReader;
            }
예제 #6
0
        public static Optional <MatchResult <InterfaceDetails> > Interface(IReadStringContent reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var identifiedInterface   = false;
            var interfaceName         = Optional <IdentifierDetails> .Missing;
            var genericTypeParameters = Optional <ImmutableList <GenericTypeParameterDetails> > .Missing;
            var baseTypes             = Optional <ImmutableList <NamedTypeDetails> > .Missing;
            var properties            = ImmutableList <PropertyDetails> .Empty;
            var readerAfterValue      = reader
                                        .StartMatching()
                                        .Then(Match("interface"))
                                        .Then(Whitespace)
                                        .IfDefined(() => identifiedInterface = true)
                                        .ThenOptionally(Whitespace)
                                        .Then(Identifier, value => interfaceName = value)
                                        .ThenOptionally(Whitespace)
                                        .If(Match('<')).Then(GenericTypeParameters, value => genericTypeParameters = value)
                                        .ThenOptionally(Whitespace)
                                        .ThenOptionally(InheritanceChain, value => baseTypes = value)
                                        .ThenOptionally(Whitespace)
                                        .Then(Match('{'))
                                        .ThenOptionally(Whitespace)
                                        .ThenOptionally(InterfaceProperties, value => properties = value)
                                        .ThenOptionally(Whitespace)
                                        .Then(Match('}'));

            if (!readerAfterValue.IsDefined)
            {
                if (identifiedInterface)
                {
                    throw new ArgumentException($"Invalid interface content starting at {reader.Index}");
                }
                return(null);
            }
            if (genericTypeParameters.IsDefined && !genericTypeParameters.Value.Any())
            {
                throw new ArgumentException($"Invalid interface content starting at {reader.Index} - has generic type param opening bracket but zero type params present");
            }

            return(MatchResult.New(
                       new InterfaceDetails(
                           interfaceName.Value,
                           genericTypeParameters.GetValueOrDefault(ImmutableList <GenericTypeParameterDetails> .Empty),
                           baseTypes.GetValueOrDefault(ImmutableList <NamedTypeDetails> .Empty),
                           properties,
                           new SourceRangeDetails(reader.Index, readerAfterValue.Value.Index - reader.Index)
                           ),
                       readerAfterValue.Value
                       ));
        }
        public MatchResult(T result, IReadStringContent reader)
        {
            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            Result = result;
            Reader = reader;
        }
        public ParsedContent(ImmutableList <IType> types, IReadStringContent reader)
        {
            if (types == null)
            {
                throw new ArgumentNullException(nameof(types));
            }
            if (types.Any(t => t == null))
            {
                throw new ArgumentException("Null reference encountered in set", nameof(types));
            }

            Types  = types;
            Reader = reader;
        }
        public static string ReadRemainingContent(this IReadStringContent reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var content = new StringBuilder();

            while (reader.Current != null)
            {
                content.Append(reader.Current);
                reader = reader.GetNext();
            }
            return(content.ToString());
        }
예제 #10
0
        private static Optional <MatchResult <NamedTypeDetails> > BaseType(IReadStringContent reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var result = InheritanceChain(reader, supportMultipleBaseTypes: false);

            if (!result.IsDefined)
            {
                return(null);
            }

            return(MatchResult.New(result.Value.Result.Single(), result.Value.Reader));
        }
예제 #11
0
        public static Optional <MatchResult <IdentifierDetails> > Identifier(IReadStringContent reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var result = reader.MatchAnythingUntil(IdentifierDetails.DisallowedCharacters);

            if (!result.IsDefined)
            {
                return(null);
            }

            return(MatchResult.New(
                       new IdentifierDetails(result.Value.Result, GetSourceRangeFromReaders(reader, result.Value.Reader)),
                       result.Value.Reader
                       ));
        }
        private static IEnumerable <CharacterAndNextReader> Read(this IReadStringContent reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            while (true)
            {
                var currentCharacter = reader.Current;
                if (currentCharacter == null)
                {
                    yield break;
                }

                var nextReader = reader.GetNext();
                yield return(new CharacterAndNextReader(currentCharacter.Value, nextReader));

                reader = nextReader;
            }
        }
        /// <summary>
        /// At least one terminator character must be specified, otherwise all of the remaining content would be returned
        /// </summary>
        public static Optional <MatchResult <string> > MatchAnythingUntil(this IReadStringContent reader, ImmutableList <char> acceptableTerminators)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            if (acceptableTerminators == null)
            {
                throw new ArgumentNullException(nameof(acceptableTerminators));
            }
            if (!acceptableTerminators.Any())
            {
                throw new ArgumentException("at least one terminator character must be specified", nameof(acceptableTerminators));
            }

            var matchedCharacters = reader
                                    .Read()
                                    .TakeWhile(c => !acceptableTerminators.Contains(c.Character));

            // Ensure some content was actually read (if not then return a no-data result)
            if (!matchedCharacters.Any())
            {
                return(null);
            }

            // Ensure that the content was correctly terminated (the content may have been exhausted, which is not the same as identifying content that
            // was explicitly terminated by one of a particular set of characters - if no terminator was met then it a no-data result must be returned)
            var readerAfterMatch = matchedCharacters.Last().NextReader;

            if (readerAfterMatch.Current == null)
            {
                return(null);
            }

            return(MatchResult.New(
                       string.Join("", matchedCharacters.Select(c => c.Character)),
                       readerAfterMatch
                       ));
        }
예제 #14
0
 private static Optional <MatchResult <ImmutableList <NamedTypeDetails> > > InheritanceChain(IReadStringContent reader) => InheritanceChain(reader, supportMultipleBaseTypes: true);
예제 #15
0
        private static Optional <MatchResult <ImmutableList <NamedTypeDetails> > > InheritanceChain(IReadStringContent reader, bool supportMultipleBaseTypes)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var readerAtTypeList = reader.StartMatching().Then(Match("extends"));

            if (!readerAtTypeList.IsDefined)
            {
                return(null);
            }

            var baseTypes = ImmutableList <NamedTypeDetails> .Empty;

            while (true)
            {
                if (baseTypes.Any())
                {
                    var readerAfterTypeParameterSeparator = readerAtTypeList.ThenOptionally(Whitespace).Then(Match(','));
                    if (readerAfterTypeParameterSeparator.IsDefined)
                    {
                        readerAtTypeList = readerAfterTypeParameterSeparator;
                    }
                }

                var name             = Optional <NamedTypeDetails> .Missing;
                var readerAfterValue = readerAtTypeList
                                       .ThenOptionally(Whitespace)
                                       .Then(NamedType, value => name = value);
                if (!readerAfterValue.IsDefined)
                {
                    break;
                }
                baseTypes        = baseTypes.Add(name.Value);
                readerAtTypeList = readerAfterValue;
                if (!supportMultipleBaseTypes)
                {
                    break;
                }
            }
            return(MatchResult.New(baseTypes, readerAtTypeList.Value));
        }
예제 #16
0
        public static Optional <MatchResult <ImmutableList <GenericTypeParameterDetails> > > GenericTypeParameters(IReadStringContent reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var readerAtTypeParameterDefinition = reader.StartMatching().Then(Match('<'));

            if (!readerAtTypeParameterDefinition.IsDefined)
            {
                return(null);
            }

            var genericTypeParameters = ImmutableList <GenericTypeParameterDetails> .Empty;

            while (true)
            {
                var readerAfterImminentClosingBrace = readerAtTypeParameterDefinition.ThenOptionally(Whitespace).Then(Match('>'));
                if (readerAfterImminentClosingBrace.IsDefined)
                {
                    reader = readerAfterImminentClosingBrace.Value;
                    break;
                }
                if (genericTypeParameters.Any())
                {
                    var readerAfterTypeParameterSeparator = readerAtTypeParameterDefinition.ThenOptionally(Whitespace).Then(Match(','));
                    if (readerAfterTypeParameterSeparator.IsDefined)
                    {
                        readerAtTypeParameterDefinition = readerAfterTypeParameterSeparator;
                    }
                }

                var name             = Optional <NamedTypeDetails> .Missing;
                var typeConstraint   = Optional <NamedTypeDetails> .Missing;
                var readerAfterValue = readerAtTypeParameterDefinition
                                       .ThenOptionally(Whitespace)
                                       .Then(NamedType, value => name = value)
                                       .ThenOptionally(Whitespace)
                                       .If(Match("extends")).Then(BaseType, value => typeConstraint = value);
                if (!readerAfterValue.IsDefined)
                {
                    break;
                }
                genericTypeParameters = genericTypeParameters.Add(new GenericTypeParameterDetails(
                                                                      name.Value,
                                                                      typeConstraint
                                                                      ));
                readerAtTypeParameterDefinition = readerAfterValue;
            }
            return(MatchResult.New(genericTypeParameters, reader));
        }
예제 #17
0
        public static Optional <MatchResult <TypeDescriptionDetails> > TypeDescription(IReadStringContent reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var result = reader.MatchAnythingUntil(UntilWhiteSpaceOrPunctuation);

            if (!result.IsDefined)
            {
                return(null);
            }

            return(MatchResult.New(
                       new TypeDescriptionDetails(result.Value.Result, GetSourceRangeFromReaders(reader, result.Value.Reader)),
                       result.Value.Reader
                       ));
        }
예제 #18
0
        private static Optional <MatchResult <ImmutableList <PropertyDetails> > > InterfaceProperties(IReadStringContent reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var contents = ImmutableList <PropertyDetails> .Empty;

            while (true)
            {
                var identifier       = Optional <IdentifierDetails> .Missing;
                var typeDescription  = Optional <TypeDescriptionDetails> .Missing;
                var readerAfterValue = reader
                                       .StartMatching()
                                       .ThenOptionally(Whitespace)
                                       .Then(Identifier, value => identifier = value)
                                       .ThenOptionally(Whitespace)
                                       .Then(Match(':'))
                                       .ThenOptionally(Whitespace)
                                       .Then(TypeDescription, value => typeDescription = value)
                                       .ThenOptionally(Whitespace)
                                       .Then(Match(';'));
                if (!readerAfterValue.IsDefined)
                {
                    break;
                }

                contents = contents.Add(new PropertyDetails(identifier.Value, typeDescription.Value));
                reader   = readerAfterValue.Value;
            }
            if (!contents.Any())
            {
                return(null);
            }
            return(MatchResult.New(contents, reader));
        }