Feature/identification#51
Conversation
…undew.Base into feature/Identification # Conflicts: # Source/Sundew.Base.Identification/IValueIdentifiable.cs # Source/Sundew.Base.Identification/Path.cs # Source/Sundew.Base.Identification/Source.cs # Source/Sundew.Base.Identification/Sundew.Base.Identification.csproj # Source/Sundew.Base.Identification/Target.cs # Source/Sundew.Base.Identification/TargetEvaluator.cs # Source/Sundew.Base.Identification/ValueIdBuilder.cs
Partial support for InstanceIds in ValueId
There was a problem hiding this comment.
Pull request overview
This PR introduces a new identification/parsing feature set to the Sundew.Base codebase, adds supporting result/collection changes needed by that feature, and expands the test project to cover parts of the new API surface.
Changes:
- Add new
Sundew.Base.IdentificationandSundew.Base.Parsingprojects with ID, value, target, lexer, and parser primitives. - Extend result/union-related primitives and collection equality behavior to support the new APIs and newer discriminated-union generation.
- Update tests, solution/project wiring, and central package versions to include the new feature area.
Reviewed changes
Copilot reviewed 69 out of 70 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
Source/Sundew.Base.slnx |
Adds the new Identification and Parsing projects to the solution. |
Source/Sundew.Base.Threading/ValueSynchronizer.cs |
Removes a stale commented line in cancellation handling. |
Source/Sundew.Base.Threading/PostSubmitAction.cs |
Marks nested records as partial for source-generation compatibility. |
Source/Sundew.Base.Primitives/Sundew.Base.Primitives.csproj |
Normalizes package reference formatting. |
Source/Sundew.Base.Primitives/R{TSuccess}.cs |
Adds true/false operators to the success-only result type. |
Source/Sundew.Base.Primitives/R{TSuccess,TError}.cs |
Replaces implicit bool conversion with true/false operators. |
Source/Sundew.Base.Primitives/RoE{TError}.cs |
Adds true/false operators to the error-only result type. |
Source/Sundew.Base.Primitives/ResultOfErrorExtensions.cs |
Adds RoE chaining helpers via extension blocks. |
Source/Sundew.Base.Primitives/ResultExtensions.cs |
Adds And combinators for composing result tuples. |
Source/Sundew.Base.Primitives/Failure.cs |
Marks union records as partial. |
Source/Sundew.Base.Parsing/Sundew.Base.Parsing.csproj |
Adds the new Parsing library project. |
Source/Sundew.Base.Parsing/RegexLexerRule.cs |
Implements regex-backed lexer rules. |
Source/Sundew.Base.Parsing/ParserDebugView.cs |
Adds a debugger proxy for parser state inspection. |
Source/Sundew.Base.Parsing/Parser.cs |
Introduces the core parser state machine and accept/undo helpers. |
Source/Sundew.Base.Parsing/ParseSettings.cs |
Adds parse settings configuration type. |
Source/Sundew.Base.Parsing/LexerError.cs |
Defines lexer error union types. |
Source/Sundew.Base.Parsing/Lexer.cs |
Implements token-to-rule dispatch for lexing. |
Source/Sundew.Base.Parsing/ILexerRule.cs |
Defines the lexer rule contract. |
Source/Sundew.Base.Parsing/ILexer.cs |
Defines the lexer contract. |
Source/Sundew.Base.Identification/ValueIdBuilder.cs |
Builds ValueId instances from object members. |
Source/Sundew.Base.Identification/ValueId.cs |
Adds ValueId parsing, formatting, and conversion helpers. |
Source/Sundew.Base.Identification/TargetEvaluator.cs |
Resolves source/path metadata into reflection types. |
Source/Sundew.Base.Identification/Target.cs |
Adds target parsing and type-introspection APIs. |
Source/Sundew.Base.Identification/Sundew.Base.Identification.csproj |
Adds the new Identification library project. |
Source/Sundew.Base.Identification/Source.cs |
Adds source formatting/parsing and type resolution. |
Source/Sundew.Base.Identification/SequenceIdExtensions.cs |
Adds sequence-id generation and comparison helpers. |
Source/Sundew.Base.Identification/SequenceId.cs |
Stores per-id-type sequence counters. |
Source/Sundew.Base.Identification/Segment.cs |
Adds path segment representation and formatting. |
Source/Sundew.Base.Identification/ScalarValue.cs |
Adds scalar value serialization. |
Source/Sundew.Base.Identification/RevisionId.cs |
Adds a revision sequence-id type. |
Source/Sundew.Base.Identification/Properties/AssemblyInfo.cs |
Exposes internals to the test project. |
Source/Sundew.Base.Identification/Path.cs |
Adds path representation and formatting. |
Source/Sundew.Base.Identification/Parsing/Tokens.cs |
Defines lexer tokens for ID parsing. |
Source/Sundew.Base.Identification/Parsing/IdRouteParser.cs |
Implements parsing for ids, routes, arguments, and values. |
Source/Sundew.Base.Identification/Parsing/IParserError.cs |
Defines parser error unions for Identification parsing. |
Source/Sundew.Base.Identification/Parsing/Grammar.cs |
Defines the Identification grammar separators/tokens. |
Source/Sundew.Base.Identification/LiteralValue.cs |
Adds literal value serialization. |
Source/Sundew.Base.Identification/InstanceId.cs |
Adds an instance sequence-id type. |
Source/Sundew.Base.Identification/IdRoute.cs |
Adds route parsing for chained ids. |
Source/Sundew.Base.Identification/Id.cs |
Adds the main ID representation, formatting, and expression helpers. |
Source/Sundew.Base.Identification/IValueIdentifiable.cs |
Defines value-identifiable contract. |
Source/Sundew.Base.Identification/IValue.cs |
Defines the value union contract. |
Source/Sundew.Base.Identification/ISequenceId.cs |
Defines sequence-id contract. |
Source/Sundew.Base.Identification/IIdentifiable.cs |
Defines generic identifiable contract. |
Source/Sundew.Base.Identification/ExpressionEvaluator.cs |
Converts expressions into sources, paths, and arguments. |
Source/Sundew.Base.Identification/ComplexValue.cs |
Adds complex/named value serialization. |
Source/Sundew.Base.Identification/ArrayValue.cs |
Adds array value serialization. |
Source/Sundew.Base.Identification/Arguments.cs |
Adds argument collection formatting. |
Source/Sundew.Base.Identification/Argument.cs |
Adds named argument formatting. |
Source/Sundew.Base.Identification/AppendOptions.cs |
Adds append configuration for value formatting. |
Source/Sundew.Base.Development.Tests/Threading/ManualResetEventAsyncTests.cs |
Adjusts one async wait test. |
Source/Sundew.Base.Development.Tests/Sundew.Base.Development.Tests.csproj |
Adds Identification reference and coverlet settings to tests. |
Source/Sundew.Base.Development.Tests/Migrations/System_Text_Json/MigrationTests.cs |
Updates migration test records to partial. |
Source/Sundew.Base.Development.Tests/Migrations/System_Text_Json/DeserializationTests.cs |
Updates deserialization test record to partial. |
Source/Sundew.Base.Development.Tests/Migrations/MigrationCancellationTests.cs |
Updates cancellation test records to partial. |
Source/Sundew.Base.Development.Tests/Migrations/DiscriminatedUnionMigrationsTests.cs |
Updates migration union test records to partial. |
Source/Sundew.Base.Development.Tests/Identification/RevisionIdTests.cs |
Adds tests for sequence-id increment/overflow behavior. |
Source/Sundew.Base.Development.Tests/Identification/IdTests.cs |
Adds broad tests for ID formatting, parsing, and type inspection. |
Source/Sundew.Base.Development.Tests/Collections/ValueListTests.cs |
Adds equality coverage for default vs empty value lists. |
Source/Sundew.Base.Development.Tests/Collections/ValueDictionaryTests.cs |
Adds equality coverage for default vs empty value dictionaries. |
Source/Sundew.Base.Development.Tests/Collections/ValueArrayTests.cs |
Adds equality coverage for default vs empty value arrays. |
Source/Sundew.Base.Collections.Linq/Single.cs |
Marks Single<T> as partial. |
Source/Sundew.Base.Collections.Linq/Multiple.cs |
Marks Multiple<T> as partial. |
Source/Sundew.Base.Collections.Linq/Item.cs |
Adds result-to-item helpers for collection pipelines. |
Source/Sundew.Base.Collections.Linq/Empty.cs |
Marks Empty<T> as partial. |
Source/Sundew.Base.Collections.Immutable/ValueList{TItem}.cs |
Changes equality to treat default and empty lists as equal. |
Source/Sundew.Base.Collections.Immutable/ValueDictionary{TKey,TValue}.cs |
Changes equality to treat default and empty dictionaries as equal. |
Source/Sundew.Base.Collections.Immutable/ValueArray{TItem}.cs |
Changes equality to treat default and empty arrays as equal. |
Source/Directory.Packages.props |
Updates central package versions. |
Source/Directory.Build.targets |
Suppresses TFM support warnings for older target frameworks. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| public bool Equals(ValueDictionary<TKey, TValue> other) | ||
| { | ||
| if (this.Count == 0 && other.Count == 0) | ||
| { | ||
| return true; |
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Already fixed in d6ac42d — GetHashCode() for ValueDictionary now returns 0 when Count == 0, consistent with the equality rule.
| public bool Equals(ValueArray<TItem> other) | ||
| { | ||
| if (this.Count == 0 && other.Count == 0) | ||
| { | ||
| return true; |
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Already fixed in d6ac42d — GetHashCode() for ValueArray now returns 0 when Count == 0, consistent with the equality rule.
| return new R<(TSuccess1, TSuccess2, TSuccess3, TSuccess4), TError>(false, default, otherResult.Error); | ||
| } | ||
|
|
||
| return new R<(TSuccess1, TSuccess2, TSuccess3, TSuccess4), TError>(true, default, result.Error); |
| var match = regex.Match(input, state.Position); | ||
| if (match.Success) |
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Fixed in c4f8bc9. Added match.Index == state.Position to the success check, so matches that start after the current position are rejected instead of being accepted.
| var argument = complexValue.Items.FirstOrDefault(x => x.Name == referenceName); | ||
| if (argument.HasValue) | ||
| { | ||
| return TValue.Parse(argument.ValueId.Value.ToString() ?? string.Empty, formatProvider); |
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Fixed in cee067e. GetScalar now pattern-matches on ScalarValue to access its raw Value string directly instead of calling .ToString() (which applies Uri.EscapeDataString). This ensures strings with reserved characters round-trip correctly through TValue.Parse.
| public bool Equals(ValueList<TItem> other) | ||
| { | ||
| if (this.Count == 0 && other.Count == 0) | ||
| { | ||
| return true; |
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Fixed in d6ac42d. Updated GetHashCode() in all three types (ValueList, ValueArray, ValueDictionary) to return 0 when Count == 0, consistent with the equality rule that treats default and Empty as equal. Equal instances now always produce the same hash code.
| public bool Undo() | ||
| { | ||
| return this.stateStack.TryPop(out var _); | ||
| } |
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Fixed in 030e9c9. Undo() now checks stateStack.Count > 1 before popping, so the initial state (pushed in the constructor) is never removed. Calling Undo() when there is nothing to roll back now safely returns false and leaves the stack intact.
| string? fragment = null; | ||
| if (parser.TryAccept(Grammar.LiteralSeparator)) | ||
| { | ||
| var valueIdsResult = Arguments(parser); | ||
| if (valueIdsResult.IsSuccess) | ||
| { | ||
| arguments = valueIdsResult.Value; | ||
| } | ||
| else | ||
| { | ||
| return R.Error(IIdError._IdValueIdError(valueIdsResult.Error)); | ||
| } |
| if (arguments.HasValue) | ||
| { | ||
| return arguments.Items.Select(x => x.ValueId.TryGetType()).AllOrFailed(x => x.ToItem()).Map(x => (IReadOnlyList<Type>)x.Items); |
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Fixed in 030e9c9. GetInputTypes now first attempts metadata-based type resolution for all arguments. When that fails (e.g. primitive/default arguments that omit metadata), it falls back to looking up the method's parameter types from the member signature — using per-argument metadata where available and the declared parameter type as the fallback for each argument individually.
…y when Count == 0 Equal instances (default and Empty) now always return the same hash code (0) when Count == 0, fixing the Equals/GetHashCode contract violation that broke hash-based collections. Agent-Logs-Url: https://github.com/sundews/Sundew.Base/sessions/d77bd4d4-f942-4427-be6b-c50f0d860b48 Co-authored-by: hugener <5023998+hugener@users.noreply.github.com>
…undew.Base into feature/Identification
… to fall back to member signature for primitive arguments - Parser.Undo(): now returns false and leaves stack intact when only the initial state remains, preventing InvalidOperationException on subsequent Peek() calls - TargetEvaluator.GetInputTypes(): when argument metadata-based type resolution fails (e.g. for primitives without metadata), falls back to the target method's parameter types from the member signature Agent-Logs-Url: https://github.com/sundews/Sundew.Base/sessions/4ed14592-e3bd-41bb-ad4d-b9f6fcdf2e89 Co-authored-by: hugener <5023998+hugener@users.noreply.github.com>
ScalarValue.ToString() returns Uri.EscapeDataString output (wire format). Using it in TValue.Parse() caused round-trip failures for strings with reserved characters. Now pattern-matching on ScalarValue to access the raw Value property directly. Agent-Logs-Url: https://github.com/sundews/Sundew.Base/sessions/5cbb2907-948b-43e1-8b28-653475331fdb Co-authored-by: hugener <5023998+hugener@users.noreply.github.com>
Agent-Logs-Url: https://github.com/sundews/Sundew.Base/sessions/5cbb2907-948b-43e1-8b28-653475331fdb Co-authored-by: hugener <5023998+hugener@users.noreply.github.com>
…sition Regex.Match(input, startat) can return a match starting after startat. Added match.Index == state.Position check to ensure only matches at the exact current position are accepted. Agent-Logs-Url: https://github.com/sundews/Sundew.Base/sessions/28a3fb6e-d0d3-4a43-a06b-da8e4615a660 Co-authored-by: hugener <5023998+hugener@users.noreply.github.com>
…le-item case - Fix array parsing loop: use IsNext(ArrayEnd) instead of IsNext(GroupStart) so [Blue,Green] style arrays correctly terminate at ']' - Fix IdRoute do-while loop: use TryAccept(IdSeparator) without negation so a single-id route with no trailing '>' exits cleanly at end-of-input - Fix ValueIdBuilder.Build() Single case: wrap in ComplexValue with metadata instead of returning single.Item.ValueId bare, preserving round-trip identity Agent-Logs-Url: https://github.com/sundews/Sundew.Base/sessions/605f58c5-a131-42fb-af81-b359b3a1aa79 Co-authored-by: hugener <5023998+hugener@users.noreply.github.com>
…undew.Base into feature/Identification
No description provided.