2
2
3
3
import com .intellij .openapi .diagnostic .Logger ;
4
4
import com .intellij .psi .*;
5
+ import com .intellij .util .containers .Stack ;
5
6
import org .intellij .sequencer .diagram .Info ;
6
7
import org .intellij .sequencer .util .PsiUtil ;
7
8
10
11
import java .util .List ;
11
12
12
13
public class SequenceGenerator extends JavaElementVisitor {
14
+ private final Stack <PsiCallExpression > _exprStack = new Stack <PsiCallExpression >();
15
+ private final Stack <CallStack > _callStack = new Stack <CallStack >();
13
16
private static final Logger LOGGER = Logger .getInstance (SequenceGenerator .class .getName ());
14
17
15
18
private CallStack topStack ;
@@ -22,7 +25,7 @@ public SequenceGenerator(SequenceParams params) {
22
25
}
23
26
24
27
public void visitElement (PsiElement psiElement ) {
25
- PsiUtil .acceptChildren (psiElement , this );
28
+ psiElement .acceptChildren (this );
26
29
}
27
30
28
31
public void visitClass (PsiClass psiClass ) {
@@ -35,35 +38,43 @@ public CallStack generate(PsiMethod psiMethod) {
35
38
36
39
public void visitMethod (PsiMethod psiMethod ) {
37
40
MethodDescription method = createMethod (psiMethod );
38
- if (topStack == null ) {
41
+ if (topStack == null ) {
39
42
topStack = new CallStack (method );
40
43
currentStack = topStack ;
41
44
} else {
42
- if (!params .isAllowRecursion () && currentStack .isReqursive (method ))
45
+ if (!params .isAllowRecursion () && currentStack .isReqursive (method ))
43
46
return ;
44
47
currentStack = currentStack .methodCall (method );
45
48
}
46
49
super .visitMethod (psiMethod );
47
50
}
48
51
49
- public void visitNewExpression (PsiNewExpression psiNewExpression ) {
50
- PsiMethod psiMethod = psiNewExpression .resolveConstructor ();
51
- methodCall (psiMethod );
52
- super .visitNewExpression (psiNewExpression );
53
- }
54
-
55
- public void visitMethodCallExpression (PsiMethodCallExpression psiMethodCallExpression ) {
56
- PsiMethod psiMethod = psiMethodCallExpression .resolveMethod ();
57
- methodCall (psiMethod );
58
- super .visitMethodCallExpression (psiMethodCallExpression );
52
+ @ Override
53
+ public void visitCallExpression (PsiCallExpression callExpression ) {
54
+ if (!(PsiUtil .isComplexCall (callExpression ) || PsiUtil .isPipeline (callExpression ))) {
55
+ PsiMethod psiMethod = callExpression .resolveMethod ();
56
+ methodCall (psiMethod );
57
+ } else {
58
+ _exprStack .push (callExpression );
59
+ _callStack .push (currentStack );
60
+ }
61
+ super .visitCallExpression (callExpression );
62
+ if ((PsiUtil .isPipeline (callExpression ) || PsiUtil .isComplexCall (callExpression )))
63
+ if (!_exprStack .isEmpty ()) {
64
+ CallStack old = currentStack ;
65
+ PsiCallExpression pop = _exprStack .pop ();
66
+ currentStack = _callStack .pop ();
67
+ methodCall (pop .resolveMethod ());
68
+ currentStack = old ;
69
+ }
59
70
}
60
71
61
72
private void methodCall (PsiMethod psiMethod ) {
62
- if (psiMethod == null )
73
+ if (psiMethod == null )
63
74
return ;
64
- if (!params .getMethodFilter ().allow (psiMethod ))
75
+ if (!params .getMethodFilter ().allow (psiMethod ))
65
76
return ;
66
- else if (depth < params .getMaxDepth () - 1 ) {
77
+ else if (depth < params .getMaxDepth () - 1 ) {
67
78
CallStack oldStack = currentStack ;
68
79
depth ++;
69
80
LOGGER .debug ("+ depth = " + depth + " method = " + psiMethod .getName ());
@@ -79,7 +90,7 @@ private MethodDescription createMethod(PsiMethod psiMethod) {
79
90
PsiParameter [] parameters = psiMethod .getParameterList ().getParameters ();
80
91
List argNames = new ArrayList ();
81
92
List argTypes = new ArrayList ();
82
- for (int i = 0 ; i < parameters .length ; i ++) {
93
+ for (int i = 0 ; i < parameters .length ; i ++) {
83
94
PsiParameter parameter = parameters [i ];
84
95
argNames .add (parameter .getName ());
85
96
PsiType psiType = parameter .getType ();
@@ -90,35 +101,36 @@ private MethodDescription createMethod(PsiMethod psiMethod) {
90
101
if (containingClass == null ) {
91
102
containingClass = (PsiClass ) psiMethod .getParent ().getContext ();
92
103
}
93
- if (psiMethod .isConstructor ())
104
+ if (psiMethod .isConstructor ())
94
105
return MethodDescription .createConstructorDescription (
95
- createClassDescription (containingClass ),
96
- attributes , argNames , argTypes );
106
+ createClassDescription (containingClass ),
107
+ attributes , argNames , argTypes );
97
108
return MethodDescription .createMethodDescription (
98
- createClassDescription (containingClass ),
99
- attributes , psiMethod .getName (), psiMethod .getReturnType ().getCanonicalText (),
100
- argNames , argTypes );
109
+ createClassDescription (containingClass ),
110
+ attributes , psiMethod .getName (), psiMethod .getReturnType ().getCanonicalText (),
111
+ argNames , argTypes );
101
112
}
102
113
103
114
private ClassDescription createClassDescription (PsiClass psiClass ) {
104
115
return new ClassDescription (psiClass .getQualifiedName (),
105
- createAttributes (psiClass .getModifierList ()));
116
+ createAttributes (psiClass .getModifierList ()));
106
117
}
107
118
108
119
private List createAttributes (PsiModifierList psiModifierList ) {
109
- if (psiModifierList == null )
120
+ if (psiModifierList == null )
110
121
return Collections .EMPTY_LIST ;
111
122
List attributes = new ArrayList ();
112
- for (int i = 0 ; i < Info .RECOGNIZED_METHOD_ATTRIBUTES .length ; i ++) {
123
+ for (int i = 0 ; i < Info .RECOGNIZED_METHOD_ATTRIBUTES .length ; i ++) {
113
124
String attribute = Info .RECOGNIZED_METHOD_ATTRIBUTES [i ];
114
- if (psiModifierList .hasModifierProperty (attribute ))
125
+ if (psiModifierList .hasModifierProperty (attribute ))
115
126
attributes .add (attribute );
116
127
}
117
- if (PsiUtil .isInClassFile (psiModifierList ) || PsiUtil .isInJarFileSystem (psiModifierList ))
128
+ if (PsiUtil .isInClassFile (psiModifierList ) || PsiUtil .isInJarFileSystem (psiModifierList ))
118
129
attributes .add (Info .EXTERNAL_ATTRIBUTE );
119
130
return attributes ;
120
131
}
121
132
122
133
public void visitReferenceExpression (PsiReferenceExpression psiReferenceExpression ) {
134
+ psiReferenceExpression .acceptChildren (this );
123
135
}
124
136
}
0 commit comments