Skip to content

Conversation

@Mr-Rm
Copy link
Collaborator

@Mr-Rm Mr-Rm commented Dec 17, 2025

  • классы, относящиеся к ТаблицеЗначений переработаны для ускорения в случае, когда индексов нет
  • в Рефлекторе упрощено добавление колонок в разные таблицы

Нужны ли ОписанияТипов в таблицах, формируемых Рефлектором? Ведь запись в них не производится.

Summary by CodeRabbit

  • Bug Fixes

    • Fewer spurious column-name errors and clearer missing-column reporting.
    • Prevented unnecessary index notifications when updating or inserting non-indexed data.
  • Improvements

    • More reliable index lifecycle (add/remove/clear) and safer initial index rebuilding.
    • Centralized column creation/validation and consistent table/type construction.
    • Slight performance and behavior tweaks in row insertion, lookup and count handling.
  • Public API

    • New column indexability controls and index-management methods introduced.

✏️ Tip: You can customize this high-level summary in your review settings.


Note

Speeds up ValueTable by avoiding unnecessary index updates via index-aware columns, simplifies Reflector table creation, and refactors TypeDescription building with a SortedSet-based comparer.

  • ValueTable / Indexing:
    • Make ValueTableColumn index-aware (IsIndexable, AddToIndex, DeleteFromIndex) and update CollectionIndex to manage column index refs and rebuild on init.
    • Avoid index notifications when no indexes; clear/rebuild indexes in bulk ops (Add, Insert, LoadColumn, FillValues).
    • Add CollectionIndex.ExcludeFields; ensure proper cleanup on index/collection delete/clear.
    • Improve FindRows to use a suitable index (suitableIndex?.GetData(...)); add GetColumnOrThrow for consistent column lookup.
  • Reflector:
    • Use ValueTable.Columns.AddUnchecked(...) for fast column setup; build annotation tables via column indices; unify property/method table schemas without explicit type descriptions.
  • TypeDescriptions:
    • Replace list-based storage with SortedSet + TypeComparer; filter out Undefined.
    • Simplify TypeDescription.StringType/IntegerType/BooleanType constructors; minor comparer/dictionary tweaks.

Written by Cursor Bugbot for commit 186a8bf. This will update automatically on new commits. Configure here.

@Mr-Rm Mr-Rm marked this pull request as draft December 17, 2025 21:09
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 17, 2025

Walkthrough

Refactors ValueTable indexing and column management: adds per-column index tracking and APIs, changes column constructor signature, centralizes column-name validation, adjusts index lifecycle/population and index-notification gating, and replaces several internal collections with concrete or sorted types.

Changes

Cohort / File(s) Summary
Collection index
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs
Switched internal _data to concrete Dictionary; constructor marks ValueTableColumn fields indexable and populates index from source; simplified CanBeUsedFor; changed field-removal to fully remove occurrences and call DeleteFromIndex/Rebuild; added ExcludeFields; made Clear expression-bodied.
Index collection & lifecycle
src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs
Removed automatic Rebuild in Add; Count() uses list.Count; Delete/Clear now call ExcludeFields before removal/clearing; BuildFieldList now returns List<IValue>, trims/splits input, looks up columns and throws on unknown names.
ValueTable core
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs
Added GetColumnOrThrow helper; replaced direct name lookups with it; FindRows uses null-conditional index selection; Add and Insert guard index notifications and make row creation lazy on Insert.
Row updates
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs
Count() made expression-bodied; Set() only issues index notifications (ElementRemoved / ElementAdded) when column.IsIndexable.
Column model
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs
Removed id parameter from constructor; made _valueType readonly; added _indicesCount and public IsIndexable plus AddToIndex() / DeleteFromIndex() to manage index tracking.
Column collection & name handling
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs
Replaced per-instance comparer with static case-insensitive comparer; added AddUnchecked overloads; added CheckColumnName helper; refactored Add/Insert to use centralized validation and removed id auto-increment.
Reflector table construction
src/OneScript.StandardLibrary/Reflector.cs
Use AddUnchecked for columns, switch to index-based FindColumnByIndex for annotation tables, various local-variable caching and formatting adjustments.
Type descriptions & builder
src/OneScript.StandardLibrary/TypeDescriptions/TypeDescription.cs, src/OneScript.StandardLibrary/TypeDescriptions/TypeDescriptionBuilder.cs, src/OneScript.StandardLibrary/TypeDescriptions/TypeComparer.cs
Replaced builder chains with direct TypeDescription construction for simple types; changed primitives type to Dictionary; switched internal _types to SortedSet (with TypeComparer) and filter out undefined types; simplified add/remove/build behaviors.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas needing extra attention:

  • Updated ValueTableColumn constructor signature and all call sites.
  • Index lifecycle: interplay of AddToIndex/DeleteFromIndex, ExcludeFields, and Rebuild.
  • Index notification gating in ValueTable.Add / Insert and ValueTableRow.Set.
  • BuildFieldList parsing and its new throwing behavior for unknown column names.
  • TypeDescriptionBuilder change to SortedSet and filtering of undefined types.

Possibly related PRs

Suggested reviewers

  • EvilBeaver

Poem

🐰 I hopped through rows with curious cheer,
I marked each column that I hold dear,
Dropped the old ids, trimmed names just so,
Kept indexes tidy — watch them grow! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.40% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'V2: оптимизация ТаблицыЗначений и Рефлектора' directly describes the main changes: optimization of ValueTable and Reflector classes, which aligns with the primary objectives of performance improvements in ValueTable operations and simplification of Reflector's column-addition mechanisms.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@EvilBeaver
Copy link
Owner

Нужны ли ОписанияТипов в таблицах, формируемых Рефлектором?

Я думаю, что нет, но наверное надо спросить тех, кто им активно пользуется: @sfaqer @nixel2007

var annotationsTable = new ValueTable();
annotationsTable.Columns.Add("Имя");
annotationsTable.Columns.Add("Параметры");
annotationsTable.Columns.AddUnchecked("Имя","Имя");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Еще можно, наверное, оптимизировать СкопироватьКолонки, чтобы там был минимум проверок (они сделаны для исходной таблицы) потом таблицу с нужной структурой закешировать в рефлекторе, а инстансы создавать через СкопироватьКолонки.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, рассматривал подобный вариант. Тоже надо отдельную функцию заводить.

@sfaqer
Copy link
Contributor

sfaqer commented Dec 18, 2025

Нужны ли ОписанияТипов в таблицах, формируемых Рефлектором?

Я думаю, что нет, но наверное надо спросить тех, кто им активно пользуется: @sfaqer @nixel2007

Я думаю что особого смысла нет.

@Mr-Rm
Copy link
Collaborator Author

Mr-Rm commented Dec 18, 2025

Тогда уберу. AdjustValue съедает много времени

@Mr-Rm Mr-Rm marked this pull request as ready for review December 19, 2025 12:43
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs (1)

132-147: Inconsistent field name in exception message.

The exception on line 142 uses the untrimmed fieldName from the split result, but the lookup uses the trimmed name. This could cause confusing error messages with leading/trailing whitespace in the column name.

🔎 Proposed fix to use trimmed name in exception
         foreach (var fieldName in fieldNames)
         {
             var name = fieldName.Trim();
-            var field = source.GetField(name) ?? throw ColumnException.WrongColumnName(fieldName);
+            var field = source.GetField(name) ?? throw ColumnException.WrongColumnName(name);
             fields.Add(field);
         }
🧹 Nitpick comments (6)
src/OneScript.StandardLibrary/TypeDescriptions/TypeDescriptionBuilder.cs (1)

40-48: Consider null-safety for the types parameter.

The AddTypes method iterates over types without a null check. While SourceDescription calls source.TypesInternal() which returns a non-null IEnumerable, the method is public within the class and could be called with null from other paths.

🔎 Proposed defensive null check
 public TypeDescriptionBuilder AddTypes(IEnumerable<BslTypeValue> types)
 {
+    if (types == null)
+        return this;
+
     foreach (var type in types)
     {
         if (type.TypeValue.ImplementingClass != typeof(BslUndefinedValue))
             _types.Add(type);
     }
     return this;
 }
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs (1)

90-100: Good optimization, but minor code duplication.

The optimization to skip index operations for non-indexable columns is the key performance improvement. The logic is correct.

Consider extracting the common assignment to reduce duplication:

🔎 Proposed refactor to reduce duplication
 public void Set(ValueTableColumn column, IValue value)
 {
     if (column.IsIndexable)
     {
         _owner.Indexes.ElementRemoved(this);
-        _data[column] = column.ValueType.AdjustValue(value);
-        _owner.Indexes.ElementAdded(this);
     }
-    else
-        _data[column] = column.ValueType.AdjustValue(value);
+
+    _data[column] = column.ValueType.AdjustValue(value);
+
+    if (column.IsIndexable)
+    {
+        _owner.Indexes.ElementAdded(this);
+    }
 }
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (1)

43-46: Minor inefficiency: ToHashSet() allocates on every call.

CanBeUsedFor is called during FindRows to locate suitable indexes. Creating a new HashSet on each call adds allocation overhead.

🔎 Proposed optimization using HashSet for _fields

Consider caching the fields as a HashSet<IValue> alongside the list, or use a more direct comparison if the number of fields is typically small:

-return _fields.Count>0 && _fields.ToHashSet().IsSubsetOf(searchFields);
+return _fields.Count > 0 && _fields.All(f => searchFields.Contains(f));

Or if searchFields is typically a small collection and you want the subset semantics:

+private readonly HashSet<IValue> _fieldsSet = new HashSet<IValue>();
// populate _fieldsSet alongside _fields in constructor
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs (1)

69-76: Good optimization, but Insert() is inconsistent.

Add() now checks if there are any indexes before calling ElementAdded, but Insert() at line 93 unconditionally calls Indexes.ElementAdded(row). Consider applying the same optimization for consistency.

🔎 Proposed fix for Insert()
 public ValueTableRow Insert(int index)
 {
     var row = new ValueTableRow(this);
     if (index < 0 || index > _rows.Count)
         _rows.Add(row); // для совместимости с 1С, хотя логичней было бы исключение
     else
         _rows.Insert(index, row);

-    Indexes.ElementAdded(row);
+    if (Indexes.Count() > 0)
+        Indexes.ElementAdded(row);
     return row;
 }
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (1)

27-27: Consider restricting IsIndexable setter access.

The IsIndexable property has a public setter, allowing external code to modify indexing behavior at any time. If this is intentional to support dynamic index control, it's fine. However, if indexability should only be set during column creation, consider making the setter internal or replacing the auto-property with { get; internal set; } to prevent unintended modifications from user scripts.

📝 Alternative with restricted access
-public bool IsIndexable { get; set; }
+public bool IsIndexable { get; internal set; }
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs (1)

38-50: Consider adding XML documentation to AddUnchecked methods.

These public methods bypass validation for performance optimization, which is appropriate for internal scenarios like the Reflector. However, they lack XML documentation comments explaining:

  • When they should be used vs. the regular Add method
  • That they skip name validation
  • The implications of bypassing validation

Adding documentation would help prevent misuse and clarify intent.

📝 Suggested documentation
+/// <summary>
+/// Adds a column without name validation. Use only when column name validity is guaranteed.
+/// </summary>
+/// <param name="name">Column name (not validated)</param>
+/// <param name="title">Column title</param>
+/// <param name="type">Type description</param>
+/// <returns>The created column</returns>
 public ValueTableColumn AddUnchecked(string name, string title, TypeDescription type = null)
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 682f5ae and 9a26c02.

📒 Files selected for processing (10)
  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (2 hunks)
  • src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs (2 hunks)
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs (6 hunks)
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (1 hunks)
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs (4 hunks)
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs (1 hunks)
  • src/OneScript.StandardLibrary/Reflector.cs (18 hunks)
  • src/OneScript.StandardLibrary/TypeDescriptions/TypeComparer.cs (1 hunks)
  • src/OneScript.StandardLibrary/TypeDescriptions/TypeDescription.cs (1 hunks)
  • src/OneScript.StandardLibrary/TypeDescriptions/TypeDescriptionBuilder.cs (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (.cursor/rules/langversion.mdc)

Do not use C# language features that are not available in C# 8 when generating code for projects using .NET 8.0 with LangVersion 8

Files:

  • src/OneScript.StandardLibrary/TypeDescriptions/TypeComparer.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs
  • src/OneScript.StandardLibrary/TypeDescriptions/TypeDescription.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs
  • src/OneScript.StandardLibrary/Reflector.cs
  • src/OneScript.StandardLibrary/TypeDescriptions/TypeDescriptionBuilder.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs
  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs
🧠 Learnings (2)
📚 Learning: 2025-12-18T16:13:05.448Z
Learnt from: Mr-Rm
Repo: EvilBeaver/OneScript PR: 1636
File: src/OneScript.StandardLibrary/StringOperations.cs:155-157
Timestamp: 2025-12-18T16:13:05.448Z
Learning: Guideline: In OneScript, when a method parameter has a concrete type (e.g., string) and is called from scripts with omitted arguments, the runtime passes an empty string "" rather than null. Direct (non-script) calls to the method may still pass null, so implement defensive null checks for these parameters in public methods that can be called from scripts. Treat empty string as a legitimate value for script calls, and explicitly handle null for direct calls (e.g., fail fast, throw ArgumentNullException, or normalize to "" where appropriate). This should apply to all C# methods that may be invoked from OneScript with optional string parameters across the codebase.

Applied to files:

  • src/OneScript.StandardLibrary/TypeDescriptions/TypeComparer.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs
  • src/OneScript.StandardLibrary/TypeDescriptions/TypeDescription.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs
  • src/OneScript.StandardLibrary/Reflector.cs
  • src/OneScript.StandardLibrary/TypeDescriptions/TypeDescriptionBuilder.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs
  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs
📚 Learning: 2025-12-05T07:24:02.362Z
Learnt from: EvilBeaver
Repo: EvilBeaver/OneScript PR: 1623
File: src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs:84-94
Timestamp: 2025-12-05T07:24:02.362Z
Learning: In OneScript's ValueTable.Insert method (src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs), when the index parameter is negative or greater than the row count (index < 0 || index > _rows.Count), the new row should be appended to the end of the table. This behavior matches 1C platform compatibility, where out-of-bounds insertion adds rows to the end rather than throwing an exception.

Applied to files:

  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs
🧬 Code graph analysis (8)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs (2)
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (2)
  • ElementRemoved (86-93)
  • ElementAdded (73-84)
src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs (2)
  • ElementRemoved (119-125)
  • ElementAdded (111-117)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (3)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs (6)
  • ValueTableColumn (38-43)
  • ValueTableColumn (45-50)
  • ValueTableColumn (167-170)
  • ValueTableColumn (172-177)
  • ValueTableColumn (221-240)
  • ValueTableColumnCollection (33-36)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs (1)
  • ValueTableColumn (149-152)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs (1)
  • ValueTableColumn (318-320)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs (3)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (1)
  • ValueTableColumn (29-38)
src/OneScript.Core/Commons/Utils.cs (1)
  • Utils (12-54)
src/OneScript.StandardLibrary/Collections/Exceptions/ColumnException.cs (7)
  • ColumnException (13-53)
  • ColumnException (15-18)
  • ColumnException (20-22)
  • ColumnException (24-29)
  • ColumnException (31-36)
  • ColumnException (38-43)
  • ColumnException (46-51)
src/OneScript.StandardLibrary/TypeDescriptions/TypeDescription.cs (6)
src/OneScript.StandardLibrary/TypeDescriptions/TypeDescriptionBuilder.cs (1)
  • TypeDescription (83-102)
src/OneScript.Core/Values/BslTypeValue.cs (3)
  • BslTypeValue (12-54)
  • BslTypeValue (16-19)
  • BslTypeValue (21-21)
src/OneScript.StandardLibrary/TypeDescriptions/NumberQualifiers.cs (2)
  • NumberQualifiers (21-28)
  • ScriptConstructor (92-104)
src/OneScript.StandardLibrary/TypeDescriptions/StringQualifiers.cs (2)
  • StringQualifiers (19-24)
  • ScriptConstructor (84-89)
src/OneScript.StandardLibrary/TypeDescriptions/DateQualifiers.cs (2)
  • DateQualifiers (20-23)
  • ScriptConstructor (70-74)
src/OneScript.StandardLibrary/TypeDescriptions/BinaryDataQualifiers.cs (2)
  • BinaryDataQualifiers (18-23)
  • ScriptConstructor (50-54)
src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs (3)
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (2)
  • Count (120-123)
  • IValue (106-118)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs (4)
  • IValue (264-279)
  • IValue (281-293)
  • IValue (745-748)
  • IValue (763-766)
src/OneScript.StandardLibrary/Collections/Exceptions/ColumnException.cs (7)
  • ColumnException (13-53)
  • ColumnException (15-18)
  • ColumnException (20-22)
  • ColumnException (24-29)
  • ColumnException (31-36)
  • ColumnException (38-43)
  • ColumnException (46-51)
src/OneScript.StandardLibrary/TypeDescriptions/TypeDescriptionBuilder.cs (2)
src/OneScript.StandardLibrary/TypeDescriptions/TypeComparer.cs (2)
  • TypeComparer (14-64)
  • TypeComparer (54-62)
src/OneScript.StandardLibrary/TypeDescriptions/TypeDescription.cs (1)
  • IEnumerable (79-82)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs (3)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs (6)
  • Count (122-122)
  • ValueTableColumn (38-43)
  • ValueTableColumn (45-50)
  • ValueTableColumn (167-170)
  • ValueTableColumn (172-177)
  • ValueTableColumn (221-240)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs (4)
  • Count (27-30)
  • Count (32-32)
  • ValueTableColumn (149-152)
  • ValueTableRow (22-25)
src/OneScript.StandardLibrary/Collections/Exceptions/ColumnException.cs (7)
  • ColumnException (13-53)
  • ColumnException (15-18)
  • ColumnException (20-22)
  • ColumnException (24-29)
  • ColumnException (31-36)
  • ColumnException (38-43)
  • ColumnException (46-51)
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (1)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (1)
  • ValueTableColumn (29-38)
🔇 Additional comments (20)
src/OneScript.StandardLibrary/TypeDescriptions/TypeComparer.cs (1)

17-17: LGTM!

Using the concrete Dictionary<,> type instead of the interface for a private static field is a valid micro-optimization that avoids interface dispatch overhead.

src/OneScript.StandardLibrary/TypeDescriptions/TypeDescription.cs (2)

157-182: LGTM!

Direct construction of TypeDescription for single-type descriptors (StringType, IntegerType, BooleanType) is a valid optimization that avoids the builder overhead while maintaining equivalent behavior. All qualifiers are properly initialized.


183-184: Attribute placement looks correct.

The [ScriptConstructor] attribute is correctly placed immediately before the Constructor method declaration.

src/OneScript.StandardLibrary/TypeDescriptions/TypeDescriptionBuilder.cs (2)

24-26: LGTM!

Using a SortedSet<BslTypeValue> with a static TypeComparer instance is a clean optimization that:

  1. Guarantees uniqueness automatically (no explicit deduplication needed)
  2. Maintains consistent ordering
  3. Reuses a single comparer instance across all builder instances

50-57: LGTM!

The simplified RemoveTypes implementation using a foreach loop is cleaner and works correctly with SortedSet.Remove().

src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs (1)

42-42: LGTM!

Using the Count property directly instead of calling a method is a minor but valid improvement.

src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (1)

95-95: LGTM!

Simplifying Clear() to an expression-bodied member is a clean style improvement.

src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs (2)

318-321: LGTM!

The GetColumnOrThrow helper centralizes column lookup and exception throwing, reducing code duplication across CheckFilterCriteria, ColumnsMap, and GetSortRules. The expression-bodied syntax is clean and appropriate.


327-327: LGTM!

All usages of GetColumnOrThrow are appropriate replacements for the previous inline lookup-and-throw patterns.

Also applies to: 367-367, 656-656

src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (2)

24-24: LGTM: Making _valueType immutable.

The readonly modifier ensures the value type cannot be changed after construction, which is correct for this scenario.


29-38: LGTM: Simplified constructor signature.

Removing the id parameter simplifies the API and aligns with the updated column creation logic in ValueTableColumnCollection. The default IsIndexable = false makes sense as an opt-in optimization.

src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs (3)

28-28: LGTM: Static comparer for case-insensitive column names.

Using a static StringComparer.OrdinalIgnoreCase is efficient and appropriate for column name lookups. This avoids creating comparer instances per collection.


53-60: LGTM: Centralized validation logic.

The CheckColumnName helper effectively consolidates validation logic from Add and Insert methods, following the DRY principle and making validation consistent.


132-132: LGTM: Consistent IValue return type.

Returning ValueFactory.Create() (undefined) instead of null when a column is not found is more consistent with OneScript's type system and matches the documented behavior.

src/OneScript.StandardLibrary/Reflector.cs (6)

31-31: Minor: Formatting improvement in attribute.

The space after the comma in [ContextClass("Рефлектор", "Reflector")] improves readability.


145-154: LGTM: Index constants and unchecked column additions.

The introduction of annotNameColumnIndex and annotParamsColumnIndex constants combined with AddUnchecked is an excellent optimization:

  • Index-based access avoids repeated string comparisons
  • AddUnchecked skips validation overhead for known-safe internal table construction
  • Constants make the code more maintainable

The indices correctly match the column creation order (Имя=0, Параметры=1).


159-160: LGTM: Consistent use of index-based column access.

Using FindColumnByIndex with the predefined constants is more efficient than name-based lookups and ensures consistency with the index constants defined earlier.


191-196: LGTM: Optimized annotation value construction.

Caching expandedValue.Columns in expandedValueColumns and using index-based access reduces redundant property accesses and lookups, improving performance.


351-356: LGTM: Consistent use of AddUnchecked for internal table construction.

Using AddUnchecked throughout the methods table construction is appropriate because:

  • The Reflector creates read-only metadata tables
  • Column names are hardcoded and guaranteed to be valid
  • This optimization aligns with the PR's goal of improving performance when indices aren't needed

According to the PR discussion, avoiding type descriptions (ОписанияТипов) in these tables further improves performance since AdjustValue is expensive and unnecessary for read-only metadata.

Based on learnings: The PR objectives mention that type descriptions will be removed from Reflector tables since they're not written to, and AdjustValue is time-consuming.


86-87: Minor: Formatting consistency.

The added line break after variable initialization improves code readability by visually separating variable declarations from subsequent logic.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (2)

21-25: Minor style inconsistency in access modifiers.

Line 21 omits the private keyword while line 24 explicitly includes it. Both are functionally equivalent since private is the default, but consider being consistent.

🔎 Proposed fix for consistency
-        readonly List<IValue> _fields = new List<IValue>();
+        private readonly List<IValue> _fields = new List<IValue>();

43-46: Minor formatting: add spacing around operator.

🔎 Proposed fix
-            return _fields.Count>0 && _fields.ToHashSet().IsSubsetOf(searchFields);
+            return _fields.Count > 0 && _fields.ToHashSet().IsSubsetOf(searchFields);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a26c02 and fc6f41b.

📒 Files selected for processing (1)
  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (.cursor/rules/langversion.mdc)

Do not use C# language features that are not available in C# 8 when generating code for projects using .NET 8.0 with LangVersion 8

Files:

  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs
🧠 Learnings (1)
📚 Learning: 2025-12-18T16:13:05.448Z
Learnt from: Mr-Rm
Repo: EvilBeaver/OneScript PR: 1636
File: src/OneScript.StandardLibrary/StringOperations.cs:155-157
Timestamp: 2025-12-18T16:13:05.448Z
Learning: Guideline: In OneScript, when a method parameter has a concrete type (e.g., string) and is called from scripts with omitted arguments, the runtime passes an empty string "" rather than null. Direct (non-script) calls to the method may still pass null, so implement defensive null checks for these parameters in public methods that can be called from scripts. Treat empty string as a legitimate value for script calls, and explicitly handle null for direct calls (e.g., fail fast, throw ArgumentNullException, or normalize to "" where appropriate). This should apply to all C# methods that may be invoked from OneScript with optional string parameters across the codebase.

Applied to files:

  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs
🧬 Code graph analysis (1)
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (2)
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndexKey.cs (3)
  • CollectionIndexKey (15-82)
  • CollectionIndexKey (20-24)
  • CollectionIndexKey (37-48)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (1)
  • ValueTableColumn (29-38)
🔇 Additional comments (2)
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (2)

27-41: Initialization order issue has been fixed.

The constructor now correctly populates _fields (lines 29-34) before iterating over _source and calling ElementAdded (lines 37-40). This ensures CollectionIndexKey.Extract receives a populated _fields collection when building index keys.


95-95: LGTM!

Concise expression-bodied member syntax is appropriate for this single-statement method.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs (1)

181-183: Suggest applying GetColumnOrThrow consistently in GetProcessingColumnList.

Lines 328, 368, and 657 now use the new GetColumnOrThrow helper for consistent column validation. However, lines 181-183 in GetProcessingColumnList still use the old pattern:

var Column = Columns.FindColumnByName(name);
if (Column == null)
    throw ColumnException.WrongColumnName(column_name);

Consider refactoring this to use GetColumnOrThrow(name) for consistency, noting that the error message currently references column_name (untrimmed) rather than name (trimmed), which may need to be preserved if intentional.

🔎 Proposed refactor for consistency
-var Column = Columns.FindColumnByName(name);
-if (Column == null)
-    throw ColumnException.WrongColumnName(column_name);
+var Column = GetColumnOrThrow(name);

If preserving the untrimmed column_name in the error message is important, consider adding an overload to GetColumnOrThrow that accepts a custom error message parameter.

Also applies to: 328-328, 351-351, 368-368, 657-657

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc6f41b and aad5791.

📒 Files selected for processing (4)
  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (2 hunks)
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs (8 hunks)
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (1 hunks)
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (.cursor/rules/langversion.mdc)

Do not use C# language features that are not available in C# 8 when generating code for projects using .NET 8.0 with LangVersion 8

Files:

  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs
🧠 Learnings (2)
📚 Learning: 2025-12-05T07:24:02.362Z
Learnt from: EvilBeaver
Repo: EvilBeaver/OneScript PR: 1623
File: src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs:84-94
Timestamp: 2025-12-05T07:24:02.362Z
Learning: In OneScript's ValueTable.Insert method (src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs), when the index parameter is negative or greater than the row count (index < 0 || index > _rows.Count), the new row should be appended to the end of the table. This behavior matches 1C platform compatibility, where out-of-bounds insertion adds rows to the end rather than throwing an exception.

Applied to files:

  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs
📚 Learning: 2025-12-18T16:13:05.448Z
Learnt from: Mr-Rm
Repo: EvilBeaver/OneScript PR: 1636
File: src/OneScript.StandardLibrary/StringOperations.cs:155-157
Timestamp: 2025-12-18T16:13:05.448Z
Learning: Guideline: In OneScript, when a method parameter has a concrete type (e.g., string) and is called from scripts with omitted arguments, the runtime passes an empty string "" rather than null. Direct (non-script) calls to the method may still pass null, so implement defensive null checks for these parameters in public methods that can be called from scripts. Treat empty string as a legitimate value for script calls, and explicitly handle null for direct calls (e.g., fail fast, throw ArgumentNullException, or normalize to "" where appropriate). This should apply to all C# methods that may be invoked from OneScript with optional string parameters across the codebase.

Applied to files:

  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs
🔇 Additional comments (3)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs (3)

87-95: LGTM: Insert optimization improves efficiency.

The refactored logic now creates the ValueTableRow only when the index is valid, avoiding unnecessary object allocation when falling back to Add(). The out-of-bounds behavior correctly delegates to Add() for 1C platform compatibility, and the index notification guard is consistent with the Add() method.

Based on learnings, this insertion behavior (out-of-bounds → append) matches the required 1C compatibility.


319-322: LGTM: Centralized column lookup improves consistency.

The new GetColumnOrThrow helper consolidates column lookup and exception handling, reducing code duplication and ensuring consistent error messages across multiple call sites.


73-74: Verify that Indexes.Count() is O(1) and confirm the optimization is sound.

The guard if (Indexes.Count() > 0) at lines 73-74 and 93-94 is a good optimization. CollectionIndexes.Count() returns _indexes.Count directly, where _indexes is a List<CollectionIndex>, making it an O(1) operation. This avoids notifying indexes when none exist, effectively implementing the PR's goal of optimizing for cases without indexes.

Also applies to: 93-94

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (2)

45-45: LGTM: CanBeUsedFor logic refactored.

The refactored logic _fields.All(f => searchFields.Contains(f)) is functionally equivalent to checking if _fields is a subset of searchFields. This is a clean refactoring with no behavioral change.


110-110: LGTM: Expression-bodied member syntax.

Converting Clear() to an expression-bodied form is a clean refactoring that improves readability without changing behavior.

src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (1)

24-24: LGTM: _valueType made readonly.

Making _valueType readonly is a good practice since it's only assigned in the constructor. This prevents accidental modifications and clarifies the immutability of this field.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aad5791 and 224b8bc.

📒 Files selected for processing (3)
  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (3 hunks)
  • src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs (2 hunks)
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (.cursor/rules/langversion.mdc)

Do not use C# language features that are not available in C# 8 when generating code for projects using .NET 8.0 with LangVersion 8

Files:

  • src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs
  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs
🧠 Learnings (2)
📚 Learning: 2025-12-05T07:24:02.362Z
Learnt from: EvilBeaver
Repo: EvilBeaver/OneScript PR: 1623
File: src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs:84-94
Timestamp: 2025-12-05T07:24:02.362Z
Learning: In OneScript's ValueTable.Insert method (src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs), when the index parameter is negative or greater than the row count (index < 0 || index > _rows.Count), the new row should be appended to the end of the table. This behavior matches 1C platform compatibility, where out-of-bounds insertion adds rows to the end rather than throwing an exception.

Applied to files:

  • src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs
📚 Learning: 2025-12-18T16:13:05.448Z
Learnt from: Mr-Rm
Repo: EvilBeaver/OneScript PR: 1636
File: src/OneScript.StandardLibrary/StringOperations.cs:155-157
Timestamp: 2025-12-18T16:13:05.448Z
Learning: Guideline: In OneScript, when a method parameter has a concrete type (e.g., string) and is called from scripts with omitted arguments, the runtime passes an empty string "" rather than null. Direct (non-script) calls to the method may still pass null, so implement defensive null checks for these parameters in public methods that can be called from scripts. Treat empty string as a legitimate value for script calls, and explicitly handle null for direct calls (e.g., fail fast, throw ArgumentNullException, or normalize to "" where appropriate). This should apply to all C# methods that may be invoked from OneScript with optional string parameters across the codebase.

Applied to files:

  • src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs
  • src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs
  • src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs
🧬 Code graph analysis (3)
src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs (1)
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (2)
  • IValue (121-133)
  • ExcludeFields (79-86)
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (2)
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndexKey.cs (3)
  • CollectionIndexKey (15-82)
  • CollectionIndexKey (20-24)
  • CollectionIndexKey (37-48)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (3)
  • ValueTableColumn (32-40)
  • AddToIndex (29-29)
  • DeleteFromIndex (30-30)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (2)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs (6)
  • ValueTableColumn (38-43)
  • ValueTableColumn (45-50)
  • ValueTableColumn (167-170)
  • ValueTableColumn (172-177)
  • ValueTableColumn (221-240)
  • ValueTableColumnCollection (33-36)
src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs (1)
  • ValueTableColumn (319-321)
🔇 Additional comments (9)
src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs (4)

39-43: LGTM!

Good micro-optimization: direct property access _indexes.Count avoids the overhead of the LINQ Count() extension method call.


45-51: LGTM!

Correct ordering: fields are excluded from the index before removal, ensuring proper cleanup and consistency with the new index lifecycle management.


53-60: LGTM!

Consistent with the Delete method: ensures all indexes have their fields properly excluded before the collection is cleared.


137-152: Subtle behavioral change for whitespace-only field names.

The previous implementation used string.IsNullOrWhiteSpace(fieldName) inside the loop to silently skip whitespace-only entries (e.g., "col1, ,col2" would process only col1 and col2).

The new implementation uses RemoveEmptyEntries, which only removes truly empty strings—whitespace-only entries like " " still pass through, get trimmed to "", and will now throw WrongColumnName when GetField("") returns null.

This is arguably more correct (errors on malformed input rather than silently ignoring), but it's a breaking change. If backward compatibility is required, restore the whitespace filtering:

Option to restore previous behavior
-            var fieldNames = fieldList.Split(',', System.StringSplitOptions.RemoveEmptyEntries);
+            var fieldNames = fieldList.Split(',');
             foreach (var fieldName in fieldNames)
             {
-                var name = fieldName.Trim();
-                var field = source.GetField(name) ?? throw ColumnException.WrongColumnName(fieldName);
-                fields.Add(field);
+                var name = fieldName.Trim();
+                if (string.IsNullOrEmpty(name))
+                    continue;
+                var field = source.GetField(name) ?? throw ColumnException.WrongColumnName(fieldName);
+                fields.Add(field);
             }
src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs (3)

24-25: LGTM: Type change to concrete Dictionary.

The change from IDictionary to Dictionary for the internal _data field is appropriate. Since this field is not exposed publicly, using the concrete type reduces unnecessary abstraction and may provide minor performance benefits.


27-41: LGTM: Constructor initialization order is now correct.

The initialization order issue flagged in previous reviews has been properly addressed. Fields are now populated into _fields (lines 29-34) before iterating _source and calling ElementAdded() (lines 37-40), ensuring that CollectionIndexKey.Extract() will produce valid keys from the start.


68-74: The while loop correctly implements reference counting. When the same column is added multiple times to _fields (which the constructor allows), AddToIndex() is called once per occurrence, incrementing ValueTableColumn._indicesCount accordingly. The while loop removes all occurrences and calls DeleteFromIndex() the same number of times, properly decrementing the counter back to zero. This is intentional and correct behavior—no action needed.

src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs (2)

27-30: LGTM: Clean index tracking implementation.

The index tracking implementation is well-designed:

  • _indicesCount tracks how many indexes reference this column
  • IsIndexable provides a fast O(1) check for index participation
  • DeleteFromIndex() includes defensive logic to prevent negative counts

This design supports the PR's optimization goal by enabling fast checks for columns not participating in any index.


32-32: LGTM: Constructor signature simplified.

Removing the id parameter simplifies the constructor and is consistent with the updated callers in ValueTableColumnCollection.cs (lines 39 and 46), where columns are now created without auto-incremented IDs.

@EvilBeaver
Copy link
Owner

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@EvilBeaver EvilBeaver merged commit f4b8b27 into EvilBeaver:develop Dec 21, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants