Talk:Editor scripts OpenOverriddenMethodDef
Script code, using Dictionary class instead of cross references[edit]
<xpp> /// <summary> /// Editor_Scripts_OpenOverriddenMethodDef_ikash, 2008-08-12 /// Navigate to the definition of a method that overrides the currently open method in a descendent class /// </summary> /// <param name="e">Currenty open editor</param> 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;
TreeNodeName methodName = treeNode.treeNodeName();
Map descendents;
MapEnumerator descendentsEnumerator;
;
if (subStr(treeNode.treeNodePath(), 1, strLen(#ClassesPath)) == #ClassesPath)
{
treeNodeParent = TreeNode::findNode(xUtilElements::getNodePathRough(xUtilElements::parentElement(xUtilElements::findTreeNode(treeNode))));
classIdParent = dictionary.className2Id(treeNodeParent.treeNodeName());
descendents = 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)
descendents.insert(treeNode.treeNodePath(), treeNode.AOTparent().treeNodeName());
}
}
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();
}
} </xpp>
Script code, outputing the result to infolog instead of a listview[edit]
This can actually save you a lot of time, if you are trying to investigate a class with a lot of descendents like RunBase, for example. You just need to run it once, and then browse the infolog results as many times as you want <xpp> /// <summary> /// Editor_Scripts_OpenOverriddenMethodDef_ikash, 2008-08-12 /// Navigate to the definition of a method that overrides the currently open method in a descendent class /// Output results to infolog (idea by Gustav from axForum.info) instead of creating a list /// </summary> /// <param name="e">Currenty open editor</param> public void addIns_OpenOverriddenMethodDef(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;
xRefTypeHierarchy xRefTypeHierarchy_find(Types _baseType, int _id)
{
xRefTypeHierarchy xRefTypeHierarchy;
select firstonly xRefTypeHierarchy
index BaseTypeIdIdx
where xRefTypeHierarchy.BaseType == _baseType &&
xRefTypeHierarchy.Id == _id;
return xRefTypeHierarchy; }
xRefTypeHierarchy xRefTypeHierarchy_findOrCreate(Types _baseType, int _id)
{
xRefTypeHierarchy xRefTypeHierarchy = xRefTypeHierarchy_find(_baseType, _id);
if (!xRefTypeHierarchy)
{
new xRefUpdateTypeHierarchy().run();
xRefTypeHierarchy = xRefTypeHierarchy_find(_baseType, _id);
}
return xRefTypeHierarchy; }
void findDescendents(ClassId _parentId)
{
xRefTypeHierarchy typeHierarchy;
TreeNode descendent;
;
if (!xRefTypeHierarchy_findOrCreate(Types::Class, _parentId).Children)
return;
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);
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:
setPrefix(@"Double-click the required line to navigatе to class or method definition:");
descendentsEnumerator = descendents.getEnumerator();
while (descendentsEnumerator.moveNext())
{
info(@"Navigate to class definition" + '\t' + descendentsEnumerator.currentValue(), ,
SysInfoAction_Editor::newOpen(#ClassesPath + #AOTDelimiter + descendentsEnumerator.currentValue()));
info(@"Navigate to method definition" + '\t' + strFmt(@"%1.%2()", descendentsEnumerator.currentValue(), methodName), ,
SysInfoAction_Editor::newOpen(descendentsEnumerator.currentKey()));
}
return;
}
if (treeNode && SysTreeNode::hasSource(treeNode))
treeNode.AOTedit();
}
} </xpp>