![]() |
#5 |
MCTS
|
ver. 1.0.3 beta, 13.06.2010
Доработано: - Реализован опциональный режим (управляется параметром #SaveGoBackPosition) сохранения в кэше исходной позиции курсора для возможности возврата с помощью скрипта AXGoBack (AXGoBack - скрипт для возврата к предыдущей позиции курсора в редакторе). Значение по умолчанию: Включен. Исправлено: - AX 3: Добавлена очистка кэша параметров после выполнения отложенного вызова функции перехода к объявлению переменной в AX 3. X++: //AXGoToDeclarationXRef ver. 1.0.3 beta (for AX 3, AX 4, AX 2009), 13.06.2010 //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 aaAXGoToDeclarationXRef(Editor e) { //Parameters section >> #define.PrintClassHierarchy(0) //1 - Print current class hierarchy in the infolog during search; 0 - Othewise; Default = 0 #define.SaveGoBackPosition(1) //1 - Save current cursor position in the Infolog's cache for using in AXGoBack script; 0 - Othewise; Default = 1 //<< Parameters section #AOT #if.ReferencesPath #define.AX4OrAX5 #endif #if.AX4OrAX5 xRefTmpReferences tmpXRefUse; #endif #ifnot.AX4OrAX5 TmpxRefReferences tmpXRefUse; SysGlobalCache globalCache; #endif #define.ClassDeclMethodPath('\\classDeclaration') #define.MethodsNodePath('\\Methods') #define.ClassHierarchyDivider(' -> ') #define.ClassHierarchyLabel('Classes: ') #define.NothingIsFoundMessage('Nothing is found.') #define.IncorrectCallMessage('Incorrect call.') #define.ThisClassCache('AXGoToDeclarationXRefClass') #define.ParamsCache('AXGoToDeclarationXRefParams') #define.GoBackParamsCache('AXGoBackParams') TreeNode treeNode; TreeNodePath curDeclMethodNodePath; //Path of current declaration method candidate Column editorColumn; Line editorLine; xRefName xRefName; TreeNodeName rootNodeName; TreeNodePath methodNodePath; //Initial method path str classHierarchy; str getElementNameFromPath(TreeNodePath _treeNodePath) { int secondBackSlashPos; int thirdBackSlashPos; ; secondBackSlashPos = strfind(_treeNodePath, '\\', 2, strlen(_treeNodePath) - 1); thirdBackSlashPos = strfind(_treeNodePath, '\\', secondBackSlashPos + 1, strlen(_treeNodePath) - secondBackSlashPos); return substr(_treeNodePath, secondBackSlashPos + 1, thirdBackSlashPos - secondBackSlashPos - 1); } boolean searchForDeclaration( TreeNodePath _treeNodePath ) { #if.AX4OrAX5 xRefTmpReferences tmpXRefDeclaration; #endif #ifnot.AX4OrAX5 TmpxRefReferences tmpXRefDeclaration; #endif ; treeNode = TreeNode::findNode(_treeNodePath); if (treeNode) { 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; } } if (xRefName) { tmpXRefDeclaration = xRefCreate::makeTmp(infolog.lastxRef()); select firstonly tmpXRefDeclaration where tmpXRefDeclaration.Reference == XRefReference::Declaration && tmpXRefDeclaration.name == xRefName ; if (tmpXRefDeclaration) { if (classHierarchy && #PrintClassHierarchy) { info(classHierarchy); } if (#SaveGoBackPosition) { infolog.globalCache().set(#GoBackParamsCache, #GoBackParamsCache, [methodNodePath, editorLine, editorColumn]); } #if.AX4OrAX5 treeNode.AOTedit(tmpXRefDeclaration.line, tmpXRefDeclaration.Column); #endif #ifnot.AX4OrAX5 infolog.globalCache().set(#ThisClassCache, #ThisClassCache, this); infolog.globalCache().set(#ParamsCache, #ParamsCache, [_treeNodePath, tmpXRefDeclaration.line, tmpXRefDeclaration.Column]); infolog.addTimeOut(this, methodstr(EditorScripts, aaAXGoToDeclarationXRef), 10, false); #endif return true; } } } return false; } boolean checkParentClassesDeclMethods(TreeNodePath _curClassDeclMethodNodePath) { #if.AX4OrAX5 xRefTmpReferences tmpXRefDeclaration; #endif #ifnot.AX4OrAX5 TmpxRefReferences tmpXRefDeclaration; #endif ; if (!classHierarchy) { classHierarchy = #ClassHierarchyLabel + getElementNameFromPath(_curClassDeclMethodNodePath); } treeNode = TreeNode::findNode(_curClassDeclMethodNodePath); treeNode.AOTmakeXref(1); tmpXRefDeclaration = xRefCreate::makeTmp(infolog.lastxRef()); select firstonly tmpXRefDeclaration where tmpXRefDeclaration.Kind == xRefKind::Class && tmpXRefDeclaration.Reference == XRefReference::Definition && tmpXRefDeclaration.ParentName ; if (tmpXRefDeclaration) { //Parent class was found classHierarchy += #ClassHierarchyDivider + tmpXRefDeclaration.ParentName; curDeclMethodNodePath = #ClassesPath + '\\' + tmpXRefDeclaration.ParentName + #ClassDeclMethodPath; if (searchForDeclaration(curDeclMethodNodePath)) { return true; } else { return checkParentClassesDeclMethods(curDeclMethodNodePath); } } else { return false; } } ; #ifnot.AX4OrAX5 //Asynchronous call of AOTedit method for AX 3 (solution of the lost focus issue) if (!e) { globalCache = infolog.globalCache(); if (globalCache) { [curDeclMethodNodePath, editorLine, editorColumn] = globalCache.get(#ParamsCache, #ParamsCache, conNull()); TreeNode::findNode(curDeclMethodNodePath).AOTedit(editorLine, editorColumn); globalCache.clear(#ThisClassCache); globalCache.clear(#ParamsCache); } return; } #endif //Init editorLine = e.currentLineNo() + 1; editorColumn = e.ColumnNo() + 1; methodNodePath = e.path(); curDeclMethodNodePath = methodNodePath; //Search in declaration block of the method itself if (searchForDeclaration(curDeclMethodNodePath)) { return; } else { if (!xRefName) { //Incorrect call info(#IncorrectCallMessage); 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 if (checkParentClassesDeclMethods(curDeclMethodNodePath)) { return; } } info(#NothingIsFoundMessage); return; } Последний раз редактировалось alex55; 13.06.2010 в 15:56. |
|
|
За это сообщение автора поблагодарили: Ansi (0), Pustik (5). |
Теги |
ax2009, ax3.0, ax4.0, tools, x++, законченный пример, инструменты, объявление переменной, полезное |
|
|