Skip to content

Commit 397ab7b

Browse files
Added ParseResult.CommandValueResult, fixed tests, and...
Removed only direct use of SymbolResultTree in ParseResult Marked the things that need to be removed/replaced to remove indirect usage (SymbolResult derived classes) Some cleanup
1 parent 5166501 commit 397ab7b

File tree

6 files changed

+91
-68
lines changed

6 files changed

+91
-68
lines changed

src/System.CommandLine.Tests/ParserTests.cs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ public void Option_short_forms_can_be_bundled()
139139

140140
var result = CliParser.Parse(command, "the-command -xyz");
141141

142-
result.CommandResult
143-
.Children
144-
.Select(o => ((OptionResult)o).Option.Name)
142+
result.CommandValueResult
143+
.ValueResults
144+
.Select(o => o.ValueSymbol.Name)
145145
.Should()
146146
.BeEquivalentTo("-x", "-y", "-z");
147147
}
@@ -1710,11 +1710,11 @@ public void CommandResult_contains_argument_ValueResults()
17101710

17111711
var parseResult = CliParser.Parse(rootCommand, "subcommand Kirk Spock");
17121712

1713-
var commandResult = parseResult.CommandResult;
1714-
commandResult.ValueResults.Should().HaveCount(2);
1715-
var result1 = commandResult.ValueResults[0];
1713+
var commandValueResult = parseResult.CommandValueResult;
1714+
commandValueResult.ValueResults.Should().HaveCount(2);
1715+
var result1 = commandValueResult.ValueResults.First();
17161716
result1.GetValue<string>().Should().Be("Kirk");
1717-
var result2 = commandResult.ValueResults[1];
1717+
var result2 = commandValueResult.ValueResults.Skip(1).First();
17181718
result2.GetValue<string>().Should().Be("Spock");
17191719
}
17201720

@@ -1735,11 +1735,11 @@ public void CommandResult_contains_option_ValueResults()
17351735

17361736
var parseResult = CliParser.Parse(rootCommand, "subcommand arg1 --opt1 Kirk --opt2 Spock");
17371737

1738-
var commandResult = parseResult.CommandResult;
1739-
commandResult.ValueResults.Should().HaveCount(2);
1740-
var result1 = commandResult.ValueResults[0];
1738+
var commandValueResult = parseResult.CommandValueResult;
1739+
commandValueResult.ValueResults.Should().HaveCount(2);
1740+
var result1 = commandValueResult.ValueResults[0];
17411741
result1.GetValue<string>().Should().Be("Kirk");
1742-
var result2 = commandResult.ValueResults[1];
1742+
var result2 = commandValueResult.ValueResults[1];
17431743
result2.GetValue<string>().Should().Be("Spock");
17441744
}
17451745

@@ -1763,9 +1763,9 @@ public void Location_in_ValueResult_correct_for_arguments()
17631763

17641764
var parseResult = CliParser.Parse(rootCommand, "subcommand Kirk Spock");
17651765

1766-
var commandResult = parseResult.CommandResult;
1767-
var result1 = commandResult.ValueResults[0];
1768-
var result2 = commandResult.ValueResults[1];
1766+
var commandValueResult = parseResult.CommandValueResult;
1767+
var result1 = commandValueResult.ValueResults[0];
1768+
var result2 = commandValueResult.ValueResults[1];
17691769
result1.Locations.Single().Should().Be(expectedLocation1);
17701770
result2.Locations.Single().Should().Be(expectedLocation2);
17711771
}
@@ -1790,9 +1790,9 @@ public void Location_in_ValueResult_correct_for_options()
17901790

17911791
var parseResult = CliParser.Parse(rootCommand, "subcommand arg1 --opt1 Kirk --opt2 Spock");
17921792

1793-
var commandResult = parseResult.CommandResult;
1794-
var result1 = commandResult.ValueResults[0];
1795-
var result2 = commandResult.ValueResults[1];
1793+
var commandValueResult = parseResult.CommandValueResult;
1794+
var result1 = commandValueResult.ValueResults[0];
1795+
var result2 = commandValueResult.ValueResults[1];
17961796
result1.Locations.Single().Should().Be(expectedLocation1);
17971797
result2.Locations.Single().Should().Be(expectedLocation2);
17981798
}
@@ -1817,8 +1817,8 @@ public void Location_offsets_in_ValueResult_correct_for_arguments()
18171817

18181818
var parseResult = CliParser.Parse(rootCommand, "subcommand Kirk Spock");
18191819

1820-
var commandResult = parseResult.CommandResult;
1821-
var result1 = commandResult.ValueResults.Single();
1820+
var commandValueResult = parseResult.CommandValueResult;
1821+
var result1 = commandValueResult.ValueResults.Single();
18221822
result1.Locations.First().Should().Be(expectedLocation1);
18231823
result1.Locations.Skip(1).Single().Should().Be(expectedLocation2);
18241824
}
@@ -1841,8 +1841,8 @@ public void Location_offsets_in_ValueResult_correct_for_options()
18411841

18421842
var parseResult = CliParser.Parse(rootCommand, "subcommand arg1 --opt1 Kirk --opt1 Spock");
18431843

1844-
var commandResult = parseResult.CommandResult;
1845-
var result1 = commandResult.ValueResults.Single();
1844+
var commandValueResult = parseResult.CommandValueResult;
1845+
var result1 = commandValueResult.ValueResults.Single();
18461846
result1.Locations.First().Should().Be(expectedLocation1);
18471847
result1.Locations.Skip(1).Single().Should().Be(expectedLocation2);
18481848
}
@@ -1867,9 +1867,9 @@ public void Location_offset_correct_when_colon_or_equal_used()
18671867

18681868
var parseResult = CliParser.Parse(rootCommand, "subcommand arg1 --opt1:Kirk --opt11=Spock");
18691869

1870-
var commandResult = parseResult.CommandResult;
1871-
var result1 = commandResult.ValueResults[0];
1872-
var result2 = commandResult.ValueResults[1];
1870+
var commandValueResult = parseResult.CommandValueResult;
1871+
var result1 = commandValueResult.ValueResults[0];
1872+
var result2 = commandValueResult.ValueResults[1];
18731873
result1.Locations.Single().Should().Be(expectedLocation1);
18741874
result2.Locations.Single().Should().Be(expectedLocation2);
18751875
}

src/System.CommandLine/ParseResult.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public sealed class ParseResult
1717
private readonly IReadOnlyDictionary<CliSymbol, ValueResult> valueResultDictionary = new Dictionary<CliSymbol, ValueResult>();
1818
private SymbolLookupByName? symbolLookupByName = null;
1919

20+
// TODO: Remove usage and remove
2021
private readonly CommandResult _rootCommandResult;
2122
// TODO: unmatched tokens, invocation, completion
2223
/*
@@ -28,10 +29,11 @@ public sealed class ParseResult
2829

2930
internal ParseResult(
3031
CliConfiguration configuration,
31-
// TODO: determine how rootCommandResult and commandResult differ
32+
// TODO: Remove RootCommandResult - it is the root of the CommandValueResult ancestors (fix that)
3233
CommandResult rootCommandResult,
34+
// TODO: Replace with CommandValueResult and remove CommandResult
3335
CommandResult commandResult,
34-
SymbolResultTree symbolResultTree,
36+
IReadOnlyDictionary<CliSymbol, ValueResult> valueResultDictionary,
3537
/*
3638
List<CliToken> tokens,
3739
*/
@@ -50,7 +52,8 @@ internal ParseResult(
5052
Configuration = configuration;
5153
_rootCommandResult = rootCommandResult;
5254
CommandResult = commandResult;
53-
valueResultDictionary = symbolResultTree.BuildValueResultDictionary();
55+
CommandValueResult = commandResult.CommandValueResult;
56+
this.valueResultDictionary = valueResultDictionary;
5457
// TODO: invocation
5558
/*
5659
_action = action;
@@ -98,8 +101,11 @@ internal ParseResult(
98101
/// <summary>
99102
/// A result indicating the command specified in the command line input.
100103
/// </summary>
104+
// TODO: Update SymbolLookupByName to use CommandValueResult, then remove
101105
internal CommandResult CommandResult { get; }
102106

107+
public CommandValueResult CommandValueResult { get; }
108+
103109
/// <summary>
104110
/// The configuration used to produce the parse result.
105111
/// </summary>
@@ -108,6 +114,7 @@ internal ParseResult(
108114
/// <summary>
109115
/// Gets the root command result.
110116
/// </summary>
117+
/// TODO: Update usage and then remove
111118
internal CommandResult RootCommandResult => _rootCommandResult;
112119

113120
/// <summary>
@@ -215,6 +222,7 @@ CommandLineText is null
215222
? result
216223
: null;
217224

225+
// TODO: Update tests and remove all use of things deriving from SymbolResult from this class
218226
/// <summary>
219227
/// Gets the result, if any, for the specified argument.
220228
/// </summary>

src/System.CommandLine/Parsing/ArgumentResult.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ public ValueResult ValueResult
3333
// TODO: Make sure errors are added
3434
var conversionValue = GetArgumentConversionResult().Value;
3535
var locations = Tokens.Select(token => token.Location).ToArray();
36-
//TODO: Remove this wrapper later
3736
_valueResult = new ValueResult(Argument, conversionValue, locations, ArgumentResult.GetValueResultOutcome(GetArgumentConversionResult()?.Result)); // null is temporary here
3837
}
3938
return _valueResult;

src/System.CommandLine/Parsing/CommandResult.cs

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,23 @@ internal CommandResult(
3838
/// </summary>
3939
public IEnumerable<SymbolResult> Children => SymbolResultTree.GetChildren(this);
4040

41-
public IReadOnlyList<ValueResult> ValueResults => Children.Select(GetValueResult).OfType<ValueResult>().ToList();
41+
private CommandValueResult? commandValueResult;
42+
public CommandValueResult CommandValueResult
43+
{
44+
get
45+
{
46+
if (commandValueResult is null)
47+
{
48+
var parent = Parent is CommandResult commandResult
49+
? commandResult.CommandValueResult
50+
: null;
51+
commandValueResult = new CommandValueResult(Command, parent);
52+
}
53+
// Reset unless we put tests in place to ensure it is not called in error handling before SymbolTree processing is complete
54+
commandValueResult.ValueResults = Children.Select(GetValueResult).OfType<ValueResult>().ToList();
55+
return commandValueResult;
56+
}
57+
}
4258

4359
private ValueResult? GetValueResult(SymbolResult symbolResult)
4460
=> symbolResult switch
@@ -59,30 +75,30 @@ internal void Validate(bool completeValidation)
5975
{
6076
if (completeValidation)
6177
{
62-
// TODO: invocation
63-
// if (Command.Action is null && Command.HasSubcommands)
78+
// TODO: invocation
79+
// if (Command.Action is null && Command.HasSubcommands)
6480
if (Command.HasSubcommands)
6581
{
6682
SymbolResultTree.InsertFirstError(
6783
new ParseError(LocalizationResources.RequiredCommandWasNotProvided(), this));
6884
}
6985

70-
// TODO: validators
71-
/*
72-
if (Command.HasValidators)
73-
{
74-
int errorCountBefore = SymbolResultTree.ErrorCount;
75-
for (var i = 0; i < Command.Validators.Count; i++)
76-
{
77-
Command.Validators[i](this);
78-
}
79-
80-
if (SymbolResultTree.ErrorCount != errorCountBefore)
81-
{
82-
return;
83-
}
84-
}
85-
*/
86+
// TODO: validators
87+
/*
88+
if (Command.HasValidators)
89+
{
90+
int errorCountBefore = SymbolResultTree.ErrorCount;
91+
for (var i = 0; i < Command.Validators.Count; i++)
92+
{
93+
Command.Validators[i](this);
94+
}
95+
96+
if (SymbolResultTree.ErrorCount != errorCountBefore)
97+
{
98+
return;
99+
}
100+
}
101+
*/
86102
}
87103

88104
// TODO: Validation
@@ -104,8 +120,8 @@ private void ValidateOptions(bool completeValidation)
104120
{
105121
var option = options[i];
106122

107-
// TODO: VersionOption, recursive options
108-
// if (!completeValidation && !(option.Recursive || option.Argument.HasDefaultValue || option is VersionOption))
123+
// TODO: VersionOption, recursive options
124+
// if (!completeValidation && !(option.Recursive || option.Argument.HasDefaultValue || option is VersionOption))
109125
if (!completeValidation && !option.Argument.HasDefaultValue)
110126
{
111127
continue;
@@ -148,23 +164,23 @@ private void ValidateOptions(bool completeValidation)
148164
continue;
149165
}
150166

151-
// TODO: validators
152-
/*
153-
if (optionResult.Option.HasValidators)
154-
{
155-
int errorsBefore = SymbolResultTree.ErrorCount;
156-
157-
for (var j = 0; j < optionResult.Option.Validators.Count; j++)
158-
{
159-
optionResult.Option.Validators[j](optionResult);
160-
}
161-
162-
if (errorsBefore != SymbolResultTree.ErrorCount)
163-
{
164-
continue;
165-
}
166-
}
167-
*/
167+
// TODO: validators
168+
/*
169+
if (optionResult.Option.HasValidators)
170+
{
171+
int errorsBefore = SymbolResultTree.ErrorCount;
172+
173+
for (var j = 0; j < optionResult.Option.Validators.Count; j++)
174+
{
175+
optionResult.Option.Validators[j](optionResult);
176+
}
177+
178+
if (errorsBefore != SymbolResultTree.ErrorCount)
179+
{
180+
continue;
181+
}
182+
}
183+
*/
168184

169185
// TODO: Ensure all argument conversions are run for entered values
170186
/*

src/System.CommandLine/Parsing/CommandValueResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ internal CommandValueResult(CliCommand command, CommandValueResult? parent = nul
2727
/// <summary>
2828
/// The ValueResult instances for user entered data. This is a sparse list.
2929
/// </summary>
30-
public IEnumerable<ValueResult> ValueResults { get; } = new List<ValueResult>();
30+
public IReadOnlyList<ValueResult> ValueResults { get; internal set; } = [];
3131

3232
/// <summary>
3333
/// The CliCommand that the result is for.

src/System.CommandLine/Parsing/ParseOperation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ internal ParseResult Parse()
8585
_configuration,
8686
_rootCommandResult,
8787
_innermostCommandResult,
88-
_rootCommandResult.SymbolResultTree,
88+
_rootCommandResult.SymbolResultTree.BuildValueResultDictionary(),
8989
/*
9090
_tokens,
9191
*/

0 commit comments

Comments
 (0)