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 )); }
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 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)); }
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)); }
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)); }