Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 80 additions & 22 deletions src/OneScript.StandardLibrary/Collections/ValueList/ValueListImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This Source Code Form is subject to the terms of the
using OneScript.Execution;
using OneScript.Types;
using OneScript.Values;
using OneScript.StandardLibrary.TypeDescriptions;
using ScriptEngine.Machine;
using ScriptEngine.Machine.Contexts;

Expand All @@ -25,18 +26,13 @@ namespace OneScript.StandardLibrary.Collections.ValueList
public class ValueListImpl : AutoCollectionContext<ValueListImpl, ValueListItem>
{
readonly List<ValueListItem> _items;

public ValueListImpl()
{
_items = new List<ValueListItem>();
}

public override bool IsIndexed
{
get
{
return true;
}
}
public override bool IsIndexed => true;

public override IValue GetIndexedValue(IValue index)
{
Expand All @@ -53,15 +49,58 @@ public override IValue GetIndexedValue(IValue index)
public override void SetIndexedValue(IValue index, IValue val)
{
if (index.SystemType == BasicTypes.Number)
throw IndexedIsReadonlyException();

base.SetIndexedValue(index, val);
}

/// <summary>
/// Определяет тип для значений, которые могут храниться в элементах данного списка значений
/// </summary>
/// <value>ОписаниеТипов</value>
[ContextProperty("ТипЗначения", "ValueType")]
public TypeDescription ListValueType { get; set; } = new();


ValueListImpl _availableValues;

/// <summary>
/// Ограничивает допустимые значения для элементов данного списка значений.
/// Возможные значения: Неопределено - ограничения отсутствуют,
/// СписокЗначений - список допустимых значений
/// </summary>
/// <remarks>
/// Проверка допустимости добавляемых значений производится после приведения к указанным в ТипЗначения (если есть)
/// </remarks>
/// <value>СписокЗначений или Неопределено</value>
[ContextProperty("ДоступныеЗначения", "AvailableValues")]
public IValue AvailableValues
{
get
{
throw new RuntimeException("Индексированное значение доступно только для чтения");
}
else
{
base.SetIndexedValue(index, val);
if (_availableValues != null)
return _availableValues;

return BslUndefinedValue.Instance;
}
}

set
{
switch (value)
{
case BslUndefinedValue:
_availableValues = null;
break;

case ValueListImpl vl:
_availableValues = vl;
break;

default: throw RuntimeException.InvalidArgumentType();
}
}
}

/// <summary>
/// Получить элемент по индексу
/// </summary>
Expand All @@ -71,6 +110,9 @@ public override void SetIndexedValue(IValue index, IValue val)
public ValueListItem GetValue(IValue index)
{
int numericIndex = (int)index.AsNumber();
if (numericIndex < 0 || numericIndex >= _items.Count)
throw RuntimeException.IndexOutOfRange();

return _items[numericIndex];
}

Expand Down Expand Up @@ -103,22 +145,28 @@ public ValueListItem Add(IValue value = null, string presentation = null, bool c
[ContextMethod("Вставить", "Insert")]
public ValueListItem Insert(int index, IValue value = null, string presentation = null, bool check = false, IValue picture = null)
{
if (index < 0 || index > _items.Count)
throw RuntimeException.IndexOutOfRange();

var newItem = CreateNewListItem(value, presentation, check, picture);
_items.Insert(index, newItem);

return newItem;
}

private static ValueListItem CreateNewListItem(IValue value, string presentation, bool check, IValue picture)
private ValueListItem CreateNewListItem(IValue value, string presentation, bool check, IValue picture)
{
var newItem = new ValueListItem
var newValue = ListValueType.AdjustValue(value);
if (_availableValues is not null)
newValue = _availableValues.FindByValue(newValue);

return new ValueListItem
{
Value = value ?? BslUndefinedValue.Instance,
Value = newValue,
Presentation = presentation,
Check = check,
Picture = picture
};
return newItem;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/// <summary>
Expand Down Expand Up @@ -194,11 +242,11 @@ private int IndexByValue(BslValue item)
{
int index;

if (item is ValueListItem)
if (item is ValueListItem listItem)
{
index = IndexOf(item as ValueListItem);
index = IndexOf(listItem);
if (index == -1)
throw new RuntimeException("Элемент не принадлежит списку значений");
throw ElementDoesntBelongException();
}
else
{
Expand All @@ -211,7 +259,7 @@ private int IndexByValue(BslValue item)
throw RuntimeException.InvalidArgumentType();
}

if (index < 0 || index >= _items.Count())
if (index < 0 || index >= _items.Count)
throw RuntimeException.IndexOutOfRange();
}

Expand All @@ -233,7 +281,7 @@ public void Move(BslValue item, int offset)

int index_dest = index_source + offset;

if (index_dest < 0 || index_dest >= _items.Count())
if (index_dest < 0 || index_dest >= _items.Count)
throw RuntimeException.InvalidNthArgumentValue(2);

ValueListItem itemObject = _items[index_source];
Expand Down Expand Up @@ -347,7 +395,17 @@ public override IEnumerator<ValueListItem> GetEnumerator()
public static ValueListImpl Constructor()
{
return new ValueListImpl();
}

public static RuntimeException IndexedIsReadonlyException()
{
return new("Индексированное значение доступно только для чтения", "Indexed value is read-only");
}

public static RuntimeException ElementDoesntBelongException()
{
return new("Элемент не принадлежит списку значений", "Element does not belong to values list");
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class ValueListItem : AutoContext<ValueListItem>
private string _presentationHolder;
private IValue _pictureHolder;

public ValueListItem()
internal ValueListItem()
{
_pictureHolder = ValueFactory.Create();
_presentationHolder = String.Empty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ This Source Code Form is subject to the terms of the
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/

using System;
using System.Collections.Generic;
using System.Text;
using OneScript.Contexts;
using OneScript.Exceptions;
using OneScript.StandardLibrary.Collections;
Expand Down Expand Up @@ -329,10 +331,13 @@ private static void CheckAndAddOneQualifier(TypeDescriptionBuilder builder, IVal
default:
throw RuntimeException.InvalidNthArgumentType(nParam);
}
}
}

internal class UndefinedTypeAdjuster : IValueAdjuster
}

public override string ToString() => string.Join(", ", _types);
}


internal class UndefinedTypeAdjuster : IValueAdjuster
{
public IValue Adjust(IValue value)
{
Expand Down
28 changes: 28 additions & 0 deletions tests/value-list.os
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
ВсеТесты.Добавить("ТестДолжен_ПроверитьМетодНайтиСпискаЗначений");
ВсеТесты.Добавить("ТестДолжен_ПроверитьМетодУдалитьСпискаЗначений");
ВсеТесты.Добавить("ТестДолжен_ПроверитьПреобразованиеЭлементаСпискаВСтроку");

ВсеТесты.Добавить("ТестДолжен_ПроверитьОшибкуМетодаПолучитьСпискаЗначений");
Возврат ВсеТесты;

КонецФункции
Expand Down Expand Up @@ -148,6 +150,32 @@
юТест.ПроверитьРавенство(СЗ.Индекс(Э3), 2, "Метод Вставить() списка значений");
юТест.ПроверитьРавенство(СЗ.Индекс(Э4), 3, "Метод Вставить() списка значений");

// Проверим ошибки
Ошибка = "Вставить с неверным индексом";
Попытка
СЗ.Вставить(10, 9);
Исключение
Ошибка = ИнформацияОбОшибке().Описание;
КонецПопытки;
юТест.ПроверитьРавенство(Ошибка, "Значение индекса выходит за пределы диапазона");

КонецПроцедуры

Процедура ТестДолжен_ПроверитьОшибкуМетодаПолучитьСпискаЗначений() Экспорт

СЗ = Новый СписокЗначений;
СЗ.Добавить("Один");
СЗ.Добавить("Два");

// Проверим ошибки
Ошибка = "Получить с неверным индексом";
Попытка
СЗ.Получить(10);
Исключение
Ошибка = ИнформацияОбОшибке().Описание;
КонецПопытки;
юТест.ПроверитьРавенство(Ошибка, "Значение индекса выходит за пределы диапазона");

КонецПроцедуры

Процедура ТестДолжен_ПроверитьМетодУдалитьСпискаЗначений() Экспорт
Expand Down