Поиск
Каждый элемент в системе обладает некоторой информацией, которая позволяет однозначно его идентифицировать среди других элементов этой системы. Впрочем делать это, предоставляя всю информацию об элементе в каждом месте его использования, достаточно трудозатратно, поэтому в платформе существует специальный алгоритм поиска, который позво ляет найти нужный элемент обладая лишь частью информации о нем (например только коротким именем и модулем, в котором используется искомый элемент).
Шаги поиска
В общем случае, алгоритм поиска состоит из одного или нескольких шагов поиска. Шаги выполняются друг за другом, таким образом, что если на первом шаге искомый элемент не был найден, выполняется второй шаг, затем следующий и так далее пока либо не будет найден искомый элемент, либо закончатся шаги (в последнем случае, платформа выдаст ошибку, что элемент не найден).
Каждый шаг поиска, в свою очередь, состоит из нескольких подшагов:
- Условия шага - множество условий, каждое из которых должно быть выполнено, чтобы шаг вообще имело смысл выполнять. Эта проверка выполняется еще до того, как начат просмотр хоть каких-то элементов системы и целиком зависит от контекста обращения.
- Условия отбора - множество условий, каждое из которых должно быть выполнено для каждого элемента, который претендует на то, чтобы быть искомым элементом. На этом шаге элементы не зависят друг от друга, а результатом выполнения этого шага является отобранное множество кандидатов, на то, чтобы быть искомым элементом.
- Операции выбора - список операций, каждая из которых фильтрует множество кандидатов, в зависимости от того, какие из кандидатов в этом множестве потенциально "лучше" (то есть с большей вероятностью) подходят на роль искомого элемента.
Если после выполнения последней операции выбора остался:
- ровно один элемент - он и считается искомым.
- больше одного элемента - платформа выдаст ошибку, что не возможно однозначно определить искомый элемент
- ни одного элемента - платформа либо перейдет на следующий шаг поиска (если он есть), либо выдаст ошибку что элемент не найден.
Ниже приведены шаги, условия и операции алгоритма поиска, в зависимости от типа искомого элемента:
Тип элемента | Шаг поиска | Условия шага | Условия отбора | Операции выбора |
---|---|---|---|---|
Модули |
| |||
Формы, Классы, Элементы навигатора, Группы свойств и действий, Таблицы, Дизайн навигатора |
| |||
Метакоды |
| |||
Свойства, Действия | Локальные |
| ||
Локальные общие | ||||
Глобальные | ||||
Глобальные общие |
|
|
Описание шагов, условий и операций алгоритма поиска:
Совпадает имя
Имя кандидата совпадает с именем поиска (всегда должно задаваться при поиске явно). Сравнение регистро-зависимое (то есть aA != AA
).
Находится в зависимом модуле
Модуль кандидата зависит от модуля, в котором осуществляется поиск.
Находится в заданном пространстве имен (если задано явно)
Пространство имен кандидата совпадает с пространством имен поиска (если это пространство имен задано явно).
Выбор приоритетного пространства имен (если пространство имен не задано явно)
Если в текущем множестве есть кандидаты из пространства имен, в котором осуществляется поиск - все остальные кандидаты удаляются из множества кандидатов, и операция выбора завершается. Если нет, аналогичное действие повторяется для приоритетных пространств имен, модуля, в котором осуществляется поиск (в порядке задания этих приоритетных пространств). Если и для них ничего не найдено, множество кандидатов остается неизменным.
Количество параметров совпадает
Количество параметров кандидата совпадает с количеством параметров обраще ния.
Поиск свойства внутри действия
Данный шаг выполняется только, для поиска свойства, причем если этот поиск идет внутри некоторого действия (а не, например, в объявлении формы).
Пространство имен не задано явно
Данный шаг выполняется только, для если пространство имен поиска не задано.
Находится сверху по стеку
Кандидат является локальным свойством и:
- объявляется внутри оператора последовательности, который выполняет действие, которое обращается к искомому элементу.
- объявляется раньше, чем действие, которое непосредственно обращается к искомому элементу.
Подходит по классам параметров
Классы параметров обращения подходят классам параметров кандидата или классы параметров обращения неизвестны.
Пересекается по классам параметров
Классы параметров обращения пересекаются с классами параметров кандидата.
Выбор более конкретных классов параметров
Если в множестве кандидатов есть свойства A
и B
, такие что классы параметров A
подходят классам параметров B
, то свойство B
удаляется из множества кандидатов.
Не поиск абстрактного свойства
Данный шаг не выполняется, если идет поиск свойства (действия) в операторе расширения свойства (действия), при чем идет поиск именно расширяемого (абстрактного) свойства (при поиске свойств в реализации используется общий механизм поиска).
Свойство абстрактное (если идет поиск абстрактного свойства)
Кандидат является абстрактным свойством (действием).
Выбор не совпадающих классов параметров (если идет поиск абстрактного свойства)
Если:
- идет поиск абстрактного свойства (действия)
- классы параметров обращения не заданы явно
- среди множества кандидатов есть свойства (действия), классы параметров которых совпадают с классами параметров обращения
- среди множества кандидатов есть свойства (действия), классы параметров которых не совпадают с классами параметров обращения
То: из множеств а кандидатов удаляются свойства (действия) из третьего пункта (то есть, у которых классы параметров совпадают с классами параметров обращения)
Дополнительные операции для поиска свойств / действий
Соответствие классов параметров
Будем говорить, что классы параметров (A1,..., An)
подходят классам параметров (B1, ..., Bm)
, если:
n=m
, то есть количество параметров совпадает- для каждого параметра
i
, одно из следующих верно:Ai
неизвестно (равно?
)Bi
неизвестно (равно?
)Ai
наследуется отBi
(а точнее множество классов-потомковBi
включает в себя множество классов-потомковAi
)
Пересечение классов параметров
Будем говорить, что классы параметров (A1,..., An)
пересекаются с классами параметров (B1, ..., Bm)
, если:
n=m
, то есть количество параметров совпадает- для каждого параметра
i
, одно из следующих верно:Ai
неизвестно (равно?
)Bi
неизвестно (равно?
)Ai
иBi
имеют общего потомка (а точнее множество классов-потомковBi
пересекается с множеством классов-потомковAi
)
Определение классов параметров обращения
При обращении к свойству (действию), если классы параметров не заданы явно, платформа пытается самостоятельно определить их из контекста обращения. Ниже приведен список (неполный) возможных контекстов, и как платформа определяет классы параметров обращения в этих случаях:
Контекст | Классы параметров обращения |
---|---|
Композиция / Вызов | Классы значений свойств-аргументов |
Использование на форме | Классы объектов подставляемых на вход искомому свойству / действию |
Добавления действия в навигатор | Пустой список |
Результаты ввода, внешнего обращения | Пустой список |
Простое разбиение | Классы значений свойств-групп (блок BY ) |
Вложенные локальные свойства в операторах работы с сессией | Неизвестно |
Импорт данных | Если импортируется список значений (LIST ), пустой список, иначе список из одного элемента INTEGER |
Определение классов параметров свойства (действия)
Если классы параметров свойства (действия) не заданы явно, платформа пытается самостоятельно определить их из реализации этого свойства (действия). Ниже приведен список (неполный) возможных реализаций, и как платформа определяет классы параметров свойства (действия) в этих случаях:
Контекст | Классы параметров обращения |
---|---|
Выражения | Классы параметров (в порядке их использования) |
Первичное, Абстрактное | Классы задаются явно в самом операторе |
Формула, Внутренний вызов | Могут задаваться явно в самом операторе, если не заданы, все классы параметров считаются неизвестными (? ), их количество определяется спецификой конкретного оператора |
Группировка | Классы значений свойств-групп (блок BY ) |
Операции с группами объектов | Классы объектов использованной группы объектов |
Примеры
MODULE ResolveA;
CLASS A;
CLASS B : A;
CLASS C : B;
f = DATA INTEGER (A);
f = DATA INTEGER (C);
META defineSmth(prm1)
x = DATA INTEGER (prm1);
END
META defineSmth(prm1, prm2)
x = DATA INTEGER (prm1, prm2);
END
MODULE ResolveB;
REQUIRE ResolveA;
f = DATA INTEGER (B);
h(C c) = f(c); // найдет верхнее объявление - ResolveB.f[B]
j(C c) = ResolveA.f(c); // найдет объявление в ResolveA - ResolveA.f[C]
z(C c) = f[A](c); // найдет объявление в ResolveA - ResolveA.f[A]
test(C c, A a) {
LOCAL f = INTEGER (B);
f(c) <- 1; // найдет верхнее объявление - f[B]
MESSAGE f(a); // найдет верхнее объявление - f[B]
ResolveB.f(c) <- 1; // найдет верхнее объявление в ResolveB - ResolveB.f[B]
}
MODULE ResolveC;
REQUIRE ResolveB, ResolveA;
NAMESPACE ResolveA;
x(B b) = f(b); // найдет объявление в ResolveA - ResolveA.f[A]
y(B b) = ResolveB.f(b); // найдет объявление в ResolveA - ResolveB.f[B]
@defineSmth(A, B); // найдет объявление в ResolveA - ResolveA.defineSmth(prm1, prm2)