Reused PyHierarchyNodeDescriptor

Removed PyCallHierarchyNodeDescriptor, updated tests to include the
new presentation of tree elements.
This commit is contained in:
Andrey Vlasovskikh
2014-09-04 17:24:38 +04:00
parent a10706f597
commit 6398722067
24 changed files with 135 additions and 375 deletions
@@ -26,6 +26,7 @@ import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiElement;
import com.intellij.ui.PopupHandler;
import com.jetbrains.python.hierarchy.PyHierarchyNodeDescriptor;
import com.jetbrains.python.hierarchy.PyHierarchyUtils;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFile;
@@ -51,18 +52,9 @@ public class PyCallHierarchyBrowser extends CallHierarchyBrowserBase {
@Nullable
@Override
protected PsiElement getElementFromDescriptor(@NotNull HierarchyNodeDescriptor descriptor) {
if (descriptor instanceof PyCallHierarchyNodeDescriptor) {
PyCallHierarchyNodeDescriptor nodeDescriptor = (PyCallHierarchyNodeDescriptor)descriptor;
return nodeDescriptor.getEnclosingElement();
}
return null;
}
@Override
protected PsiElement getOpenFileElementFromDescriptor(@NotNull HierarchyNodeDescriptor descriptor) {
if (descriptor instanceof PyCallHierarchyNodeDescriptor) {
PyCallHierarchyNodeDescriptor nodeDescriptor = (PyCallHierarchyNodeDescriptor)descriptor;
return nodeDescriptor.getTargetElement();
if (descriptor instanceof PyHierarchyNodeDescriptor) {
PyHierarchyNodeDescriptor pyDescriptor = (PyHierarchyNodeDescriptor)descriptor;
return pyDescriptor.getPsiElement();
}
return null;
}
@@ -1,240 +0,0 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.hierarchy.call;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.hierarchy.HierarchyNodeDescriptor;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.util.CompositeAppearance;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.Navigatable;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.ui.LayeredIcon;
import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author novokrest
*/
public class PyCallHierarchyNodeDescriptor extends HierarchyNodeDescriptor implements Navigatable {
private int myUsageCount = 1;
private final List<PsiReference> myReferences = new ArrayList<PsiReference>();
private final boolean myNavigateToReference;
protected PyCallHierarchyNodeDescriptor(@NotNull Project project,
@Nullable NodeDescriptor parentDescriptor,
@NotNull PsiElement element,
boolean isBase,
boolean navigateToReference) {
super(project, parentDescriptor, element, isBase);
myNavigateToReference = navigateToReference;
}
public final void incrementCount() {
myUsageCount++;
}
public final PyFunction getPyFunction() {
return (PyFunction)myElement;
}
public final PyElement getEnclosingElement() {
return PsiTreeUtil.getNonStrictParentOfType(myElement, PyFunction.class, PyClass.class, PyFile.class);
}
public final PsiElement getTargetElement() {
return myElement;
}
@Override
public boolean isValid() {
return myElement != null && myElement.isValid();
}
@Override
public boolean update() {
final CompositeAppearance oldText = myHighlightedText;
final Icon oldIcon = getIcon();
int flags = Iconable.ICON_FLAG_VISIBILITY;
if (isMarkReadOnly()) {
flags |= Iconable.ICON_FLAG_READ_STATUS;
}
final PsiElement element = getEnclosingElement();
if (element == null) {
final String invalidPrefix = IdeBundle.message("node.hierarchy.invalid");
if (!myHighlightedText.getText().startsWith(invalidPrefix)) {
myHighlightedText.getBeginning().addText(invalidPrefix, HierarchyNodeDescriptor.getInvalidPrefixAttributes());
}
return true;
}
boolean changes = super.update();
Icon newIcon = element.getIcon(flags);
if (changes && myIsBase) {
final LayeredIcon icon = new LayeredIcon(2);
icon.setIcon(newIcon, 0);
icon.setIcon(AllIcons.Hierarchy.Base, 1, -AllIcons.Hierarchy.Base.getIconWidth() / 2, 0);
newIcon = icon;
}
setIcon(newIcon);
myHighlightedText = new CompositeAppearance();
final TextAttributes mainTextAttributes = myColor != null ? null : new TextAttributes(myColor, null, null, null, Font.PLAIN);
PyElementVisitor visitor = new PyElementVisitor() {
@Override
public void visitPyClass(PyClass pyClass) {
myHighlightedText.getEnding().addText(pyClass.getName(), mainTextAttributes);
myHighlightedText.getEnding().addText("(" + pyClass.getContainingFile().getName() + ")",
HierarchyNodeDescriptor.getPackageNameAttributes());
}
@Override
public void visitPyFunction(PyFunction function) {
final StringBuilder buffer = new StringBuilder();
final PyClass pyClass = function.getContainingClass();
if (pyClass != null) {
buffer.append(pyClass.getName());
buffer.append('.');
}
buffer.append(function.getName());
myHighlightedText.getEnding().addText(buffer.toString(), mainTextAttributes);
myHighlightedText.getEnding().addText("(" + function.getContainingFile().getName() + ")",
HierarchyNodeDescriptor.getPackageNameAttributes());
}
@Override
public void visitPyLambdaExpression(PyLambdaExpression node) {
}
@Override
public void visitPyFile(PyFile pyFile) {
myHighlightedText.getEnding().addText(pyFile.getName(), mainTextAttributes);
}
};
element.accept(visitor);
if (myUsageCount > 1) {
myHighlightedText.getEnding()
.addText(IdeBundle.message("node.call.hierarchy.N.usages", myUsageCount), HierarchyNodeDescriptor.getUsageCountPrefixAttributes());
}
myName = myHighlightedText.getText();
if (!Comparing.equal(myHighlightedText, oldText)
|| !Comparing.equal(getIcon(), oldIcon)) {
return true;
}
return changes;
}
public void addReference(final PsiReference reference) {
myReferences.add(reference);
}
public boolean hasReference(final PsiReference reference) {
return myReferences.contains(reference);
}
@Override
public void navigate(boolean requestFocus) {
if (!myNavigateToReference) {
if (myElement instanceof Navigatable && ((Navigatable)myElement).canNavigate()) {
((Navigatable)myElement).navigate(requestFocus);
}
return;
}
final PsiReference firstReference = myReferences.get(0);
final PsiElement element = firstReference.getElement();
if (element == null) return;
final PsiElement callElement = element.getParent();
if (callElement instanceof Navigatable && ((Navigatable)callElement).canNavigate()) {
((Navigatable)callElement).navigate(requestFocus);
}
else {
final PsiFile file = callElement.getContainingFile();
if (file == null || file.getVirtualFile() == null) return;
FileEditorManager.getInstance(myProject).openFile(file.getVirtualFile(), requestFocus);
}
Editor editor = PsiUtilBase.findEditor(callElement);
if (editor != null) {
HighlightManager highlightManager = HighlightManager.getInstance(myProject);
EditorColorsManager colorsManager = EditorColorsManager.getInstance();
TextAttributes attributes = colorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
List<RangeHighlighter> highlighters = new ArrayList<RangeHighlighter>();
for (PsiReference reference : myReferences) {
final PsiElement eachElement = reference.getElement();
if (eachElement != null) {
PsiElement eachCallElement = eachElement.getParent();
if (eachCallElement != null) {
final TextRange textRange = eachCallElement.getTextRange();
highlightManager
.addRangeHighlight(editor, textRange.getStartOffset(), textRange.getEndOffset(), attributes, false, highlighters);
}
}
}
}
}
@Override
public boolean canNavigate() {
if (!myNavigateToReference) {
return myElement instanceof Navigatable && ((Navigatable)myElement).canNavigate();
}
if (myReferences.isEmpty()) return false;
final PsiReference reference = myReferences.get(0);
final PsiElement callElement = reference.getElement().getParent();
if (callElement == null || !callElement.isValid()) return false;
if (!(callElement instanceof Navigatable) || !((Navigatable)callElement).canNavigate()) {
final PsiFile file = callElement.getContainingFile();
if (file == null) return false;
}
return true;
}
@Override
public boolean canNavigateToSource() {
return canNavigate();
}
}
@@ -15,19 +15,20 @@
*/
package com.jetbrains.python.hierarchy.call;
import com.google.common.collect.Lists;
import com.intellij.ide.hierarchy.HierarchyNodeDescriptor;
import com.intellij.ide.hierarchy.HierarchyTreeStructure;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.hash.HashMap;
import com.jetbrains.python.hierarchy.PyHierarchyNodeDescriptor;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyFunction;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -38,46 +39,49 @@ public class PyCalleeFunctionTreeStructure extends HierarchyTreeStructure {
private final String myScopeType;
public PyCalleeFunctionTreeStructure(Project project, PsiElement element, String currentScopeType) {
super(project, new PyCallHierarchyNodeDescriptor(project, null, element, true, false));
super(project, new PyHierarchyNodeDescriptor(null, element, true));
myScopeType = currentScopeType;
}
@NotNull
@Override
protected Object[] buildChildren(@NotNull HierarchyNodeDescriptor descriptor) {
final PyElement element = ((PyCallHierarchyNodeDescriptor)descriptor).getEnclosingElement();
final boolean isCallable = element instanceof PyFunction || element instanceof PyClass || element instanceof PyFile;
HierarchyNodeDescriptor nodeDescriptor = getBaseDescriptor();
if (!isCallable || nodeDescriptor == null) {
return ArrayUtil.EMPTY_OBJECT_ARRAY;
}
final List<PsiElement> callees = Lists.newArrayList();
PyCallDataManager[] functionManagers = {
// TODO: Add dynamic call data manager
PyStaticCallDataManager.getInstance(myProject),
};
for (PyCallDataManager functionManager : functionManagers) {
callees.addAll(functionManager.getCallees(element));
}
final Map<PsiElement, PyCallHierarchyNodeDescriptor> calleeToDescriptorMap = new HashMap<PsiElement, PyCallHierarchyNodeDescriptor>();
final List<PyCallHierarchyNodeDescriptor> descriptors = Lists.newArrayList();
PsiElement baseClass = element instanceof PyFunction ? ((PyFunction)element).getContainingClass() : null;
for (PsiElement callee : callees) {
if (baseClass != null && !isInScope(baseClass, callee, myScopeType)) continue;
PyCallHierarchyNodeDescriptor calleeDescriptor = calleeToDescriptorMap.get(callee);
if (calleeDescriptor == null) {
calleeDescriptor = new PyCallHierarchyNodeDescriptor(myProject, null, callee, false, false);
calleeToDescriptorMap.put(callee, calleeDescriptor);
descriptors.add(calleeDescriptor);
final List<PyHierarchyNodeDescriptor> descriptors = new ArrayList<PyHierarchyNodeDescriptor>();
if (descriptor instanceof PyHierarchyNodeDescriptor) {
final PyHierarchyNodeDescriptor pyDescriptor = (PyHierarchyNodeDescriptor)descriptor;
final PsiElement element = pyDescriptor.getPsiElement();
final boolean isCallable = element instanceof PyFunction || element instanceof PyClass || element instanceof PyFile;
HierarchyNodeDescriptor nodeDescriptor = getBaseDescriptor();
if (!(element instanceof PyElement) || !isCallable || nodeDescriptor == null) {
return ArrayUtil.EMPTY_OBJECT_ARRAY;
}
}
final List<PsiElement> callees = new ArrayList<PsiElement>();
PyCallDataManager[] functionManagers = {
// TODO: Add dynamic call data manager
PyStaticCallDataManager.getInstance(myProject),
};
for (PyCallDataManager functionManager : functionManagers) {
callees.addAll(functionManager.getCallees((PyElement)element));
}
final Map<PsiElement, PyHierarchyNodeDescriptor> calleeToDescriptorMap = new HashMap<PsiElement, PyHierarchyNodeDescriptor>();
PsiElement baseClass = element instanceof PyFunction ? ((PyFunction)element).getContainingClass() : null;
for (PsiElement callee : callees) {
if (baseClass != null && !isInScope(baseClass, callee, myScopeType)) continue;
PyHierarchyNodeDescriptor calleeDescriptor = calleeToDescriptorMap.get(callee);
if (calleeDescriptor == null) {
calleeDescriptor = new PyHierarchyNodeDescriptor(descriptor, callee, false);
calleeToDescriptorMap.put(callee, calleeDescriptor);
descriptors.add(calleeDescriptor);
}
}
}
return ArrayUtil.toObjectArray(descriptors);
}
@@ -15,19 +15,20 @@
*/
package com.jetbrains.python.hierarchy.call;
import com.google.common.collect.Lists;
import com.intellij.ide.hierarchy.HierarchyNodeDescriptor;
import com.intellij.ide.hierarchy.HierarchyTreeStructure;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashMap;
import com.jetbrains.python.hierarchy.PyHierarchyNodeDescriptor;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyFunction;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
@@ -37,46 +38,49 @@ public class PyCallerFunctionTreeStructure extends HierarchyTreeStructure {
private final String myScopeType;
public PyCallerFunctionTreeStructure(Project project, PsiElement element, String currentScopeType) {
super(project, new PyCallHierarchyNodeDescriptor(project, null, element, true, false));
super(project, new PyHierarchyNodeDescriptor(null, element, true));
myScopeType = currentScopeType;
}
@NotNull
@Override
protected Object[] buildChildren(@NotNull HierarchyNodeDescriptor descriptor) {
final PyElement element = ((PyCallHierarchyNodeDescriptor)descriptor).getEnclosingElement();
final boolean isCallable = element instanceof PyFunction || element instanceof PyClass || element instanceof PyFile;
HierarchyNodeDescriptor nodeDescriptor = getBaseDescriptor();
if (!isCallable || nodeDescriptor == null) {
return ArrayUtil.EMPTY_OBJECT_ARRAY;
}
final List<PsiElement> callers = Lists.newArrayList();
PyCallDataManager[] functionManagers = {
// TODO: Add dynamic call data manager
PyStaticCallDataManager.getInstance(myProject),
};
for (PyCallDataManager functionManager : functionManagers) {
callers.addAll(functionManager.getCallers(element));
}
final HashMap<PsiElement, PyCallHierarchyNodeDescriptor> callerToDescriptorMap = new HashMap<PsiElement, PyCallHierarchyNodeDescriptor>();
final List<PyCallHierarchyNodeDescriptor> descriptors = Lists.newArrayList();
PsiElement baseClass = element instanceof PyFunction ? ((PyFunction)element).getContainingClass() : null;
for (PsiElement caller : callers) {
if (baseClass != null && !isInScope(baseClass, caller, myScopeType)) continue;
PyCallHierarchyNodeDescriptor callerDescriptor = callerToDescriptorMap.get(caller);
if (callerDescriptor == null) {
callerDescriptor = new PyCallHierarchyNodeDescriptor(myProject, null, caller, false, false);
callerToDescriptorMap.put(caller, callerDescriptor);
descriptors.add(callerDescriptor);
final List<PyHierarchyNodeDescriptor> descriptors = new ArrayList<PyHierarchyNodeDescriptor>();
if (descriptor instanceof PyHierarchyNodeDescriptor) {
final PyHierarchyNodeDescriptor pyDescriptor = (PyHierarchyNodeDescriptor)descriptor;
final PsiElement element = pyDescriptor.getPsiElement();
final boolean isCallable = element instanceof PyFunction || element instanceof PyClass || element instanceof PyFile;
HierarchyNodeDescriptor nodeDescriptor = getBaseDescriptor();
if (!(element instanceof PyElement) || !isCallable || nodeDescriptor == null) {
return ArrayUtil.EMPTY_OBJECT_ARRAY;
}
}
final List<PsiElement> callers = new ArrayList<PsiElement>();
PyCallDataManager[] functionManagers = {
// TODO: Add dynamic call data manager
PyStaticCallDataManager.getInstance(myProject),
};
for (PyCallDataManager functionManager : functionManagers) {
callers.addAll(functionManager.getCallers((PyElement)element));
}
final HashMap<PsiElement, PyHierarchyNodeDescriptor> callerToDescriptorMap = new HashMap<PsiElement, PyHierarchyNodeDescriptor>();
PsiElement baseClass = element instanceof PyFunction ? ((PyFunction)element).getContainingClass() : null;
for (PsiElement caller : callers) {
if (baseClass != null && !isInScope(baseClass, caller, myScopeType)) continue;
PyHierarchyNodeDescriptor callerDescriptor = callerToDescriptorMap.get(caller);
if (callerDescriptor == null) {
callerDescriptor = new PyHierarchyNodeDescriptor(descriptor, caller, false);
callerToDescriptorMap.put(caller, callerDescriptor);
descriptors.add(callerDescriptor);
}
}
}
return ArrayUtil.toObjectArray(descriptors);
}
@@ -1 +1 @@
<node text="target_func(file_1.py)" base="true"/>
<node text="target_func() (hierarchy.call.Static.ArgumentList.file_1)" base="true"/>
@@ -1 +1 @@
<node text="target_func(file_1.py)" base="true"/>
<node text="target_func() (hierarchy.call.Static.ArgumentList.file_1)" base="true"/>
@@ -1,8 +1,8 @@
<node text="A.__init__(main.py)" base="true">
<node text="invoke1(main.py)">
<node text="A.method1(main.py)"/>
<node text="A.__init__(self) (hierarchy.call.Static.Constructor.main)" base="true">
<node text="invoke1(p) (hierarchy.call.Static.Constructor.main)">
<node text="A.method1(self) (hierarchy.call.Static.Constructor.main)"/>
</node>
<node text="invoke2(main.py)">
<node text="A.method2(main.py)"/>
<node text="invoke2(p) (hierarchy.call.Static.Constructor.main)">
<node text="A.method2(self) (hierarchy.call.Static.Constructor.main)"/>
</node>
</node>
@@ -1,6 +1,6 @@
<node text="A.__init__(main.py)" base="true">
<node text="invokeA(main.py)">
<node text="C.bar(main.py)"/>
<node text="A.__init__(self) (hierarchy.call.Static.Constructor.main)" base="true">
<node text="invokeA() (hierarchy.call.Static.Constructor.main)">
<node text="C.bar(self) (hierarchy.call.Static.Constructor.main)"/>
</node>
<node text="C.bar(main.py)"/>
<node text="C.bar(self) (hierarchy.call.Static.Constructor.main)"/>
</node>
@@ -1 +1 @@
<node text="target_func(main.py)" base="true"/>
<node text="target_func() (hierarchy.call.Static.DefaultValue.main)" base="true"/>
@@ -1,4 +1,4 @@
<node text="target_func(main.py)" base="true">
<node text="func2(main.py)"/>
<node text="func4(main.py)"/>
<node text="target_func() (hierarchy.call.Static.DefaultValue.main)" base="true">
<node text="func2() (hierarchy.call.Static.DefaultValue.main)"/>
<node text="func4() (hierarchy.call.Static.DefaultValue.main)"/>
</node>
@@ -1 +1 @@
<node text="A.target_func(main.py)" base="true"/>
<node text="A.target_func(self) (hierarchy.call.Static.Inheritance.main)" base="true"/>
@@ -1,4 +1,4 @@
<node text="A.target_func(main.py)" base="true">
<node text="C.func(main.py)"/>
<node text="foo2(main.py)"/>
<node text="A.target_func(self) (hierarchy.call.Static.Inheritance.main)" base="true">
<node text="C.func(self, a) (hierarchy.call.Static.Inheritance.main)"/>
<node text="foo2(b) (hierarchy.call.Static.Inheritance.main)"/>
</node>
@@ -1,5 +1,5 @@
<node text="target_func(main.py)" base="true">
<node text="foo(main.py)">
<node text="bar(main.py)"/>
<node text="target_func() (hierarchy.call.Static.InnerFunction.main)" base="true">
<node text="foo() (hierarchy.call.Static.InnerFunction.main)">
<node text="bar() (hierarchy.call.Static.InnerFunction.main)"/>
</node>
</node>
@@ -1 +1 @@
<node text="target_func(main.py)" base="true"/>
<node text="target_func() (hierarchy.call.Static.InnerFunction.main)" base="true"/>
@@ -1,8 +1,8 @@
<node text="target_func(main.py)" base="true">
<node text="func8(file_1.py)"/>
<node text="func13(file_1.py)"/>
<node text="func15(file_1.py)"/>
<node text="inner(main.py)">
<node text="func11(file_1.py)"/>
<node text="target_func(x=func1, y=func2(), z=lambda: func3, w=lambda: func4()) (hierarchy.call.Static.Lambda.main)" base="true">
<node text="func8() (hierarchy.call.Static.Lambda.file_1)"/>
<node text="func13() (hierarchy.call.Static.Lambda.file_1)"/>
<node text="func15() (hierarchy.call.Static.Lambda.file_1)"/>
<node text="inner(ix=func7, iy=func8(), iz=lambda: func9, iw=lambda: func10()) (hierarchy.call.Static.Lambda.main)">
<node text="func11() (hierarchy.call.Static.Lambda.file_1)"/>
</node>
</node>
@@ -1 +1 @@
<node text="target_func(main.py)" base="true"/>
<node text="target_func(x=func1, y=func2(), z=lambda: func3, w=lambda: func4()) (hierarchy.call.Static.Lambda.main)" base="true"/>
@@ -1,12 +1,12 @@
<node text="target_func(main.py)" base="true">
<node text="func5(file_1.py)"/>
<node text="func3(file_1.py)"/>
<node text="func6(file_1.py)"/>
<node text="func7(file_1.py)"/>
<node text="func2(file_1.py)"/>
<node text="func1(file_1.py)"/>
<node text="func10(file_1.py)"/>
<node text="inner(main.py)">
<node text="func1(file_1.py)"/>
<node text="target_func() (hierarchy.call.Static.NestedCall.main)" base="true">
<node text="func5(*args) (hierarchy.call.Static.NestedCall.file_1)"/>
<node text="func3(*args) (hierarchy.call.Static.NestedCall.file_1)"/>
<node text="func6(*args) (hierarchy.call.Static.NestedCall.file_1)"/>
<node text="func7(*args) (hierarchy.call.Static.NestedCall.file_1)"/>
<node text="func2(*args) (hierarchy.call.Static.NestedCall.file_1)"/>
<node text="func1(*args) (hierarchy.call.Static.NestedCall.file_1)"/>
<node text="func10(*args) (hierarchy.call.Static.NestedCall.file_1)"/>
<node text="inner(*args) (hierarchy.call.Static.NestedCall.main)">
<node text="func1(*args) (hierarchy.call.Static.NestedCall.file_1)"/>
</node>
</node>
@@ -1 +1 @@
<node text="target_func(main.py)" base="true"/>
<node text="target_func() (hierarchy.call.Static.NestedCall.main)" base="true"/>
@@ -1,3 +1,3 @@
<node text="B.target_func(main.py)" base="true">
<node text="A.another_func(file_1.py)"/>
<node text="B.target_func(self, p) (hierarchy.call.Static.OverriddenMethod.main)" base="true">
<node text="A.another_func(self) (hierarchy.call.Static.OverriddenMethod.file_1)"/>
</node>
@@ -1,5 +1,5 @@
<node text="B.target_func(main.py)" base="true">
<node text="C.func1(main.py)"/>
<node text="bar1(main.py)"/>
<node text="C.func2(main.py)"/>
<node text="B.target_func(self, p) (hierarchy.call.Static.OverriddenMethod.main)" base="true">
<node text="C.func1(self, a) (hierarchy.call.Static.OverriddenMethod.main)"/>
<node text="bar1(a) (hierarchy.call.Static.OverriddenMethod.main)"/>
<node text="C.func2(self) (hierarchy.call.Static.OverriddenMethod.main)"/>
</node>
@@ -1,3 +1,3 @@
<node text="target_func(file_1.py)" base="true">
<node text="nothing(main.py)"/>
<node text="target_func() (hierarchy.call.Static.Parentheses.file_1)" base="true">
<node text="nothing(x) (hierarchy.call.Static.Parentheses.main)"/>
</node>
@@ -1,3 +1,3 @@
<node text="target_func(file_1.py)" base="true">
<node text="foo(file_1.py)"/>
<node text="target_func() (hierarchy.call.Static.Parentheses.file_1)" base="true">
<node text="foo(x=bar()) (hierarchy.call.Static.Parentheses.file_1)"/>
</node>
@@ -1,3 +1,3 @@
<node text="target_func(main.py)" base="true">
<node text="func1(main.py)"/>
<node text="target_func() (hierarchy.call.Static.Simple.main)" base="true">
<node text="func1() (hierarchy.call.Static.Simple.main)"/>
</node>
@@ -1,3 +1,3 @@
<node text="target_func(main.py)" base="true">
<node text="func2(main.py)"/>
<node text="target_func() (hierarchy.call.Static.Simple.main)" base="true">
<node text="func2() (hierarchy.call.Static.Simple.main)"/>
</node>