Показать сообщение отдельно
Старый 11.08.2008, 16:58   #17  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Я тут ухватился за
Цитата:
Сообщение от 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();
    }
}
Собственно - хотелось бы получить комментарии, замечания и пожелания
Спасибо

Последний раз редактировалось kashperuk; 12.08.2008 в 10:36. Причина: Немного улучшил производительность xRef версии
За это сообщение автора поблагодарили: aidsua (1), alex55 (1).