Я тут ухватился за
Цитата:
Сообщение от
Bishop
В тех же классах из метода базового класса уже не "перепрыгнуть" в наследника, и все-равно приходится активно работать с репозитарием.
, написал 2 варианта перехода к перекрытому методу наследника текущего класса.
Скорость работы обоих специально не сравнивал. Она зависит от результата выборки. На глаз не могу выбрать один либо второй
Кому интересно, посмотрите проект, было бы интересно, если бы кто-то замерил время.
Первый раз и там и там, ессно, выполняется долго довольно.
Через Dictionary
X++:
public void addIns_OpenOverriddenMethodDef(Editor e)
{
#AOT
#define.AOTDelimiter('\\') // This does not exist in AX versions prior to AX 2009, so I just declare it here
TreeNode treeNode = TreeNode::findNode(e.path());
TreeNode treeNodeParent;
Dictionary dictionary = new Dictionary();
Counter classCnt = dictionary.classCnt();
Counter iClassCount;
ClassId classIdParent;
ClassId classIdChild;
Counter descendentsCount;
SysDictClass dictClassChild;
TreeNodeName methodName = treeNode.treeNodeName();
Map map;
MapEnumerator mapEnumerator;
;
if (subStr(treeNode.treeNodePath(), 1, strLen(#ClassesPath)) == #ClassesPath)
{
treeNodeParent = TreeNode::findNode(xUtilElements::getNodePathRough(xUtilElements::parentElement(xUtilElements::findTreeNode(treeNode))));
classIdParent = dictionary.className2Id(treeNodeParent.treeNodeName());
map = new Map(Types::String, Types::String);
for (iClassCount = 1; iClassCount <= classCnt; iClassCount++)
{
classIdChild = dictionary.classCnt2Id(iClassCount);
if (SysDictClass::isSuperclass(classIdChild, classIdParent))
{
descendentsCount++;
treeNode = TreeNode::findNode(#ClassesPath + #AOTDelimiter + classId2Name(classIdChild) + #AOTDelimiter + methodName);
if (treeNode)
{
map.insert(treeNode.treeNodePath(), treeNode.AOTparent().treeNodeName());
}
}
}
switch (map.elements())
{
case 0:
info(strFmt("The method '%1' is not overridden in any of the %2 descendent classes", methodName, descendentsCount));
break;
case 1:
mapEnumerator = map.getEnumerator();
if (mapEnumerator.moveNext())
treeNode = TreeNode::findNode(mapEnumerator.currentKey());
else
error("Internal error. map.elements() == 1, but mapEnumerator did not find it");
break;
default:
treeNode = TreeNode::findNode(pickList(map, "Method definition", "Pick required class to go to method definition"));
}
if (treeNode && SysTreeNode::hasSource(treeNode))
treeNode.AOTedit();
}
}
Через xRef
X++:
public void addIns_OpenOverriddenMethodDefXRef(Editor e)
{
#define.AOTDelimiter('\\')
#AOT
TreeNode treeNode = TreeNode::findNode(e.path());
TreeNode treeNodeParent;
ClassId classIdParent;
TreeNodeName methodName = treeNode.treeNodeName();
Map descendents;
MapEnumerator descendentsEnumerator;
Counter descendentsCount;
void findDescendents(ClassId _parentId)
{
xRefTypeHierarchy typeHierarchy;
TreeNode descendent;
;
while select typeHierarchy
where typeHierarchy.Parent == _parentId &&
typeHierarchy.BaseType == Types::Class
{
descendentsCount++;
descendent = TreeNode::findNode(#ClassesPath + #AOTDelimiter + typeHierarchy.Name + #AOTDelimiter + methodName);
if (descendent)
descendents.insert(descendent.treeNodePath(), descendent.AOTparent().treeNodeName());
if (typeHierarchy.Children && typeHierarchy.Id)
findDescendents(typeHierarchy.Id);
}
}
;
if (subStr(treeNode.treeNodePath(), 1, strLen(#ClassesPath)) == #ClassesPath)
{
treeNodeParent = TreeNode::findNode(xUtilElements::getNodePathRough(xUtilElements::parentElement(xUtilElements::findTreeNode(treeNode))));
classIdParent = className2Id(treeNodeParent.treeNodeName());
descendents = new Map(Types::String, Types::String);
if (xRefTypeHierarchy::findOrCreate(Types::Class, classIdParent).Children)
findDescendents(classIdParent);
switch (descendents.elements())
{
case 0:
info(strFmt(@"The method '%1' is not overridden in any of the %2 descendent classes", methodName, descendentsCount));
break;
case 1:
descendentsEnumerator = descendents.getEnumerator();
if (descendentsEnumerator.moveNext())
treeNode = TreeNode::findNode(descendentsEnumerator.currentKey());
break;
default:
treeNode = TreeNode::findNode(pickList(descendents, "@SYS24724", @"Pick required class to go to method definition"));
}
if (treeNode && SysTreeNode::hasSource(treeNode))
treeNode.AOTedit();
}
}
Собственно - хотелось бы получить комментарии, замечания и пожелания
Спасибо