Перейти к основному содержимому
Версия: 5.x

Поиск

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

Шаги поиска

В общем случае, алгоритм поиска состоит из одного или нескольких шагов поиска. Шаги выполняются друг за другом, таким образом, что если на первом шаге искомый элемент не был найден, выполняется второй шаг, затем следующий и так далее пока либо не будет найден искомый элемент, либо закончатся шаги (в последнем случае, платформа выдаст ошибку, что элемент не найден).

Каждый шаг поиска, в свою очередь, состоит из нескольких подшагов:

  • Условия шага - множество условий, каждое из которых должно быть выполнено, чтобы шаг вообще имело смысл выполнять. Эта проверка выполняется еще до того, как начат просмотр хоть каких-то элементов системы и целиком зависит от контекста обращения.
  • Условия отбора - множество условий, каждое из которых должно быть выполнено для каждого элемента, который претендует на то, чтобы быть искомым элементом. На этом шаге элементы не зависят друг от друга, а результатом выполнения этого шага является отобранное множество кандидатов, на то, чтобы быть искомым элементом.
  • Операции выбора - список операций, каждая из которых фильтрует множество кандидатов, в зависимости от того, какие из кандидатов в этом множестве потенциально "лучше" (то есть с большей вероятностью) подходят на роль искомого элемента.

Если после выполнения последней операции выбора остался:

  • ровно один элемент - он и считается искомым.
  • больше одного элемента - платформа выдаст ошибку, что не возможно однозначно определить искомый элемент
  • ни одного элемента - платформа либо перейдет на следующий шаг поиска (если он есть), либо выдаст ошибку что элемент не найден.

Ниже приведены шаги, условия и операции алгоритма поиска, в зависимости от типа искомого элемента:

Тип элементаШаг поискаУсловия шагаУсловия отбораОперации выбора
Модули
  • Совпадает имя...
Формы, Классы, Элементы навигатора, Группы свойств и действий, Таблицы, Дизайн навигатора
  • Совпадает имя...
  • Находится в зависимом модуле...
  • Находится в заданном пространстве имен (если задано явно)...
  • Выбор приоритетного пространства имен (если пространство имен не задано явно)...
Метакоды
  • Совпадает имя...
  • Находится в зависимом модуле...
  • Находится в заданном пространстве имен (если задано явно)...
  • Количество параметров совпадает...
  • Выбор приоритетного пространства имен (если пространство имен не задано явно)...
Свойства, ДействияЛокальные
  • Поиск свойства внутри действия...
  • Пространство имен не задано явно...
  • Совпадает имя...
  • Находится сверху по стеку...
  • Подходит по классам параметров...
  • Выбор более конкретных классов параметров...
Локальные общие
  • Поиск свойства внутри действия...
  • Пространство имен не задано явно...
  • Совпадает имя...
  • Находится сверху по стеку...
  • Пересекается по классам параметров...
Глобальные
  • Совпадает имя...
  • Находится в зависимом модуле...
  • Находится в заданном пространстве имен (если задано явно)...
  • Подходит по классам параметров...
  • Свойство абстрактное (если идет поиск абстрактного свойства)...
  • Выбор приоритетного пространства имен (если пространство имен не задано явно)...
  • Выбор не совпадающих классов параметров (если идет поиск абстрактного свойства)...
  • Выбор более конкретных классов параметров...
Глобальные общие
  • Не поиск абстрактного свойства...
  • Совпадает имя...
  • Находится в зависимом модуле...
  • Находится в заданном пространстве имен (если задано явно)...
  • Пересекается по классам параметров...
  • Выбор приоритетного пространства имен (если пространство имен не задано явно)...

Описание шагов, условий и операций алгоритма поиска:

Совпадает имя

Имя кандидата совпадает с именем поиска (всегда должно задаваться при поиске явно). Сравнение регистро-зависимое (то есть 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)