AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 06.06.2010, 16:35   #1  
alex55 is offline
alex55
MCTS
MCBMSS
 
224 / 145 (5) +++++
Регистрация: 13.02.2007
Адрес: Москва
AXGoToDeclarationXRef - утилита перехода к объявлению переменной
Очередная вариация на тему.

Особенности:
- Работает в AX 3, AX 4, AX 2009.
- Не требует предварительного построения перекрестных ссылок.
- Не требует полного выделения имени искомой переменной, достаточно поместить курсор в любом символе имени.
- Поиск объявления переменной в текущем методе, в classDeclaration объекта текущего метода и во всех родительских классах (если данный объект является классом-наследником).

Установка:
- Добавить метод в класс EditorScripts и скомпилировать. После этого в контекстном подменю редактора Scripts/addIns появится пункт AXGoToDeclarationXRef. При необходимости вынести пункт меню на уровень выше, можно убрать символ подчеркивания из названия метода, например: aaAXGoToDeclarationXRef.

Спасибо kashperuk (Kashperuk Ivan: AxGoToDeclarationI), miklenew (Открыть в новом окне объект из кода) и Alex_KD (Axapta Development Tools) за некоторые использованные идеи.

P.S. Утилиту возврата пока не прикручивал, хочу сначала допилить ее для многоуровневого учета переходов к определению методов по Ctrl + Shift + Space (в первом варианте без субклассирования).

P.P.S. Сообщения об ошибках, конструктивная критика и идеи по доработке приветствуются.

X++:
//AXGoToDeclarationXRef ver. 1.0.0 beta (for AX 3, AX 4, AX 2009)
//Developed by alex55 (AXforum.info), 06.06.2010
//Home page: axforum.info/forums/showthread.php?t=33344
//Thanks to kashperuk, miklenew and Alex_KD from AXForum.info for some used ideas
void addIns_AXGoToDeclarationXRef(Editor e)
{
    #AOT

    #if.ReferencesPath
        #define.AX4OrAX5
    #endif

    #if.AX4OrAX5
        xRefTmpReferences   tmpXRefUse;
    #endif

    #ifnot.AX4OrAX5
        TmpxRefReferences   tmpXRefUse;
    #endif

    #define.ClassDeclMethodPath('\\classDeclaration')
    #define.MethodsNodePath('\\Methods')
    
    TreeNode            treeNode;
    TreeNodePath        curDeclMethodNodePath; //Path of current declaration method candidate
    Column              editorColumn;
    Line                editorLine;
    xRefName            xRefName;
    TreeNodeName        rootNodeName;
    
    boolean searchForDeclaration(
        TreeNodePath        _treeNodePath
    )
    {
        #if.AX4OrAX5
            xRefTmpReferences   tmpXRefDeclaration;
        #endif

        #ifnot.AX4OrAX5
             TmpxRefReferences   tmpXRefDeclaration;
        #endif
        ;

        treeNode = TreeNode::findNode(_treeNodePath);
        treeNode.AOTmakeXref(1);

        if (!tmpXRefUse)
        {
            //The tmpXRefUse is init only one time (only for original method node path)
            tmpXRefUse = xRefCreate::makeTmp(infolog.lastxRef());
            select firstonly tmpXRefUse
            order by Column desc
            where
                tmpXRefUse.line == editorLine
                && tmpXRefUse.Column <= editorColumn
            ;

            if (tmpXRefUse)
            {
                xRefName = tmpXRefUse.name;
            }
        }

        tmpXRefDeclaration = xRefCreate::makeTmp(infolog.lastxRef());

        select firstonly tmpXRefDeclaration
        where
            tmpXRefDeclaration.Reference == XRefReference::Declaration
            && tmpXRefDeclaration.name == xRefName;

        if (tmpXRefDeclaration)
        {
            TreeNode::findNode(_treeNodePath).AOTedit(tmpXRefDeclaration.line, tmpXRefDeclaration.Column);
            return true;
        }

        return false;
    }

    void checkParentClassesDeclMethods(TreeNodePath _curClassDeclMethodNodePath)
    {
        #if.AX4OrAX5
            xRefTmpReferences   tmpXRefDeclaration;
        #endif

        #ifnot.AX4OrAX5
            TmpxRefReferences   tmpXRefDeclaration;
        #endif
        ;

        treeNode = TreeNode::findNode(_curClassDeclMethodNodePath);
        treeNode.AOTmakeXref(1);
        tmpXRefDeclaration = xRefCreate::makeTmp(infolog.lastxRef());

        select firstonly tmpXRefDeclaration
        where
            tmpXRefDeclaration.Kind == xRefKind::Class
            && tmpXRefDeclaration.Reference == XRefReference::Read;

        if (tmpXRefDeclaration)
        {
            //Parent class found
            curDeclMethodNodePath = #ClassesPath + '\\' + tmpXRefDeclaration.name + #ClassDeclMethodPath;

            if (searchForDeclaration(curDeclMethodNodePath))
            {
                return;
            }
            else
            {
                checkParentClassesDeclMethods(curDeclMethodNodePath);
            }
        }

        return;
    }
    ;

    //Init
    editorLine = e.currentLineNo() + 1;
    editorColumn = e.ColumnNo() + 1;
    curDeclMethodNodePath = e.path();

    //Search in declaration block of the method itself
    if (searchForDeclaration(curDeclMethodNodePath))
    {
        return;
    }

    if (strscan(curDeclMethodNodePath, #ClassesPath, 1, strlen(curDeclMethodNodePath)))
        rootNodeName = #ClassesPath;
    else
        if (strscan(curDeclMethodNodePath, #FormsPath, 1, strlen(curDeclMethodNodePath)))
            rootNodeName = #FormsPath;
        else
            if (strscan(curDeclMethodNodePath, #ReportsPath, 1, strlen(curDeclMethodNodePath)))
                rootNodeName = #ReportsPath;
 
    if (rootNodeName)
    {
        //Search in classDeclaration method of the current class/form/report
        switch (rootNodeName)
        {
            case #ClassesPath:
                treeNode = treeNode.AOTparent();
                curDeclMethodNodePath =  treeNode.treeNodePath() + #ClassDeclMethodPath;
                break;
            case #FormsPath:
            case #ReportsPath:
                while (treeNode.treeNodePath() != rootNodeName
                )
                {
                    curDeclMethodNodePath = treeNode.treeNodePath();
                    treeNode = treeNode.AOTparent();
                }

                curDeclMethodNodePath += #MethodsNodePath + #ClassDeclMethodPath;
                break;
        }

        if (searchForDeclaration(curDeclMethodNodePath))
        {
            return;
        }
    }

    if (strscan(curDeclMethodNodePath, #ClassesPath, 1, strlen(curDeclMethodNodePath)))
    {
        //Search in classDeclaration method of all parents of the current class
        checkParentClassesDeclMethods(curDeclMethodNodePath);
    }

    return;
}

Последний раз редактировалось alex55; 06.06.2010 в 17:02. Причина: Ссылки на страницы испортились парсером при вставке.
За это сообщение автора поблагодарили: Logger (11).
Теги
ax2009, ax3.0, ax4.0, tools, x++, законченный пример, инструменты, объявление переменной, полезное

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Обновилась утилита поиска объявления переменной MikeR DAX: База знаний и проекты 26 06.06.2010 17:09
Смысл перехода с 3.0 sp5 на 4.0 или 5.0 Ватрушка DAX: Функционал 39 11.12.2009 18:32
Конфигурационная утилита и права доступа SolarWind DAX: Администрирование 4 16.10.2008 14:07
Перенос переменной в конфигураторе продукции Serg DAX: Функционал 0 09.12.2005 13:43
получение значения переменной окружения leva DAX: Программирование 3 07.10.2005 17:57

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 11:25.