blob: c5d60138299c6087646f9e05e22e15d0bb46fdc8 [file] [log] [blame]
Tor Norbyee782c572014-09-18 11:43:07 -07001/*
2 * Copyright 2000-2014 JetBrains s.r.o.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.jetbrains.python.hierarchy.call;
17
18import com.intellij.ide.hierarchy.HierarchyNodeDescriptor;
19import com.intellij.ide.hierarchy.HierarchyTreeStructure;
20import com.intellij.openapi.project.Project;
21import com.intellij.psi.PsiElement;
22import com.intellij.util.ArrayUtil;
23import com.jetbrains.python.hierarchy.PyHierarchyNodeDescriptor;
24import com.jetbrains.python.psi.PyClass;
25import com.jetbrains.python.psi.PyElement;
26import com.jetbrains.python.psi.PyFile;
27import com.jetbrains.python.psi.PyFunction;
28import org.jetbrains.annotations.NotNull;
29
30import java.util.ArrayList;
31import java.util.HashMap;
32import java.util.List;
33
34/**
35 * @author novokrest
36 */
37public abstract class PyCallHierarchyTreeStructureBase extends HierarchyTreeStructure {
38 private final String myScopeType;
39
40 public PyCallHierarchyTreeStructureBase(Project project, PsiElement element, String currentScopeType) {
41 super(project, new PyHierarchyNodeDescriptor(null, element, true));
42 myScopeType = currentScopeType;
43 }
44
45 @NotNull
46 protected abstract List<PsiElement> getChildren(@NotNull PyElement element);
47
48 @NotNull
49 @Override
50 protected Object[] buildChildren(@NotNull HierarchyNodeDescriptor descriptor) {
51 final List<PyHierarchyNodeDescriptor> descriptors = new ArrayList<PyHierarchyNodeDescriptor>();
52 if (descriptor instanceof PyHierarchyNodeDescriptor) {
53 final PyHierarchyNodeDescriptor pyDescriptor = (PyHierarchyNodeDescriptor)descriptor;
54 final PsiElement element = pyDescriptor.getPsiElement();
55 final boolean isCallable = element instanceof PyFunction || element instanceof PyClass || element instanceof PyFile;
56 HierarchyNodeDescriptor nodeDescriptor = getBaseDescriptor();
57 if (!(element instanceof PyElement) || !isCallable || nodeDescriptor == null) {
58 return ArrayUtil.EMPTY_OBJECT_ARRAY;
59 }
60
61 final List<PsiElement> children = getChildren((PyElement)element);
62
63 final HashMap<PsiElement, PyHierarchyNodeDescriptor> callerToDescriptorMap = new HashMap<PsiElement, PyHierarchyNodeDescriptor>();
64 PsiElement baseClass = element instanceof PyFunction ? ((PyFunction)element).getContainingClass() : null;
65
66 for (PsiElement caller : children) {
67 if (isInScope(baseClass, caller, myScopeType)) {
68 PyHierarchyNodeDescriptor callerDescriptor = callerToDescriptorMap.get(caller);
69 if (callerDescriptor == null) {
70 callerDescriptor = new PyHierarchyNodeDescriptor(descriptor, caller, false);
71 callerToDescriptorMap.put(caller, callerDescriptor);
72 descriptors.add(callerDescriptor);
73 }
74 }
75 }
76
77 }
78 return ArrayUtil.toObjectArray(descriptors);
79 }
80
81 @Override
82 public boolean isAlwaysShowPlus() {
83 return true;
84 }
85}