28
28
public class TryWithResourcesLineFilter extends BaseLineFilter {
29
29
private State myState = State .INITIAL ;
30
30
private int myJumpsToRemove = 0 ;
31
+ private int myExceptionVarIndex = -1 ;
31
32
32
- // INITIAL → STORE_INITIAL_EXCEPTION <--------|
33
- // ↘ ↓ |
34
- // LOAD_RESOURCE ↔ CHECK_RESOURCE_NULL |
35
- // ↕ |
36
- // CALL_CLOSE |
37
- // ↓ |
38
- // GOTO |
39
- // ↓ |
40
- // STORE_ADDITIONAL_EXCEPTION |
41
- // ↓ |
42
- // LOAD_INITIAL_EXCEPTION |
43
- // ↓ |
44
- // LOAD_ADDITIONAL_EXCEPTION |
45
- // ↓ |
46
- // CALL_ADD_SUPPRESSED ↘ |
47
- // ↓ GOTO_2 |
48
- // LOAD_INITIAL_EXCEPTION_2 ↙ |
49
- // ↕ ↘ |
50
- // CALL_CLOSE_2 THROW ------------------|
51
- // ↓
52
- // GOTO_3
33
+ // INITIAL → STORE_INITIAL_EXCEPTION/2 <-----|
34
+ // ↘ ↓ |
35
+ // ---->LOAD_RESOURCE ↔ CHECK_RESOURCE_NULL |
36
+ // | ↕ |
37
+ // | CALL_CLOSE---------------| |
38
+ // | ↓ | |
39
+ // | GOTO | |
40
+ // | ↓ | |
41
+ // | STORE_ADDITIONAL_EXCEPTION | |
42
+ // | ↓ | |
43
+ // | LOAD_INITIAL_EXCEPTION | |
44
+ // | ↓ | |
45
+ // | LOAD_ADDITIONAL_EXCEPTION | |
46
+ // | ↓ | |
47
+ // | CALL_ADD_SUPPRESSED | |
48
+ // | ↙ ↓ ↙ |
49
+ // GOTO_2 LOAD_INITIAL_EXCEPTION_2 |
50
+ // ↓ |
51
+ // THROW --------------------|
53
52
private enum State {
54
53
INITIAL ,
55
54
STORE_INITIAL_EXCEPTION ,
55
+ STORE_INITIAL_EXCEPTION_2 , // final
56
56
LOAD_RESOURCE ,
57
57
CHECK_RESOURCE_NULL ,
58
58
CALL_CLOSE , // final
@@ -64,8 +64,6 @@ private enum State {
64
64
GOTO_2 , // java 8
65
65
LOAD_INITIAL_EXCEPTION_2 ,
66
66
THROW , // final
67
- CALL_CLOSE_2 , // java 8
68
- GOTO_3 , // java 8
69
67
}
70
68
71
69
@ Override
@@ -75,39 +73,57 @@ public boolean isApplicable(InstrumentationData context) {
75
73
76
74
@ Override
77
75
protected boolean shouldRemoveLine () {
78
- return myState == State .GOTO || myState == State .THROW || myState == State .CALL_CLOSE || myState == State .GOTO_3 ;
76
+ return myState == State .GOTO || myState == State .THROW || myState == State .CALL_CLOSE
77
+ || myState == State .STORE_INITIAL_EXCEPTION_2 ;
79
78
}
80
79
81
80
@ Override
82
81
public void visitLineNumber (int line , Label start ) {
83
82
super .visitLineNumber (line , start );
84
83
myState = State .INITIAL ;
85
84
myJumpsToRemove = 0 ;
85
+ myExceptionVarIndex = -1 ;
86
86
}
87
87
88
88
@ Override
89
89
public void visitVarInsn (int opcode , int var ) {
90
90
mv .visitVarInsn (opcode , var );
91
- if ((myState == State .INITIAL || myState == State .THROW ) && opcode == Opcodes .ASTORE ) {
92
- myState = State .STORE_INITIAL_EXCEPTION ;
93
- } else if (opcode == Opcodes .ALOAD
94
- && (myState == State .STORE_INITIAL_EXCEPTION || myState == State .CHECK_RESOURCE_NULL
95
- || myState == State .INITIAL || myState == State .CALL_CLOSE )) {
96
- myState = State .LOAD_RESOURCE ;
97
- } else if (myState == State .GOTO && opcode == Opcodes .ASTORE ) {
98
- myState = State .STORE_ADDITIONAL_EXCEPTION ;
99
- } else if (myState == State .STORE_ADDITIONAL_EXCEPTION && opcode == Opcodes .ALOAD ) {
100
- myState = State .LOAD_INITIAL_EXCEPTION ;
101
- } else if (myState == State .LOAD_INITIAL_EXCEPTION && opcode == Opcodes .ALOAD ) {
102
- myState = State .LOAD_ADDITIONAL_EXCEPTION ;
103
- } else if ((myState == State .CALL_ADD_SUPPRESSED || myState == State .GOTO_2 || myState == State .CALL_CLOSE_2 )
104
- && opcode == Opcodes .ALOAD ) {
105
- myState = State .LOAD_INITIAL_EXCEPTION_2 ;
106
- } else if (myState == State .CALL_CLOSE_2 && opcode == Opcodes .GOTO ) {
107
- myState = State .GOTO_3 ;
91
+ if (opcode == Opcodes .ASTORE ) {
92
+ if (myState == State .INITIAL ) {
93
+ myState = State .STORE_INITIAL_EXCEPTION ;
94
+ myExceptionVarIndex = var ;
95
+ } else if (myState == State .THROW ) {
96
+ myState = State .STORE_INITIAL_EXCEPTION_2 ;
97
+ myExceptionVarIndex = var ;
98
+ } else if (myState == State .GOTO ) {
99
+ myState = State .STORE_ADDITIONAL_EXCEPTION ;
100
+ } else {
101
+ setHasInstructions ();
102
+ myState = State .INITIAL ;
103
+ }
104
+ } else if (opcode == Opcodes .ALOAD ) {
105
+ if (myExceptionVarIndex == var && myState == State .CALL_CLOSE ) {
106
+ myState = State .LOAD_INITIAL_EXCEPTION_2 ;
107
+ } else if (myState == State .INITIAL
108
+ || myState == State .STORE_INITIAL_EXCEPTION
109
+ || myState == State .STORE_INITIAL_EXCEPTION_2
110
+ || myState == State .CHECK_RESOURCE_NULL
111
+ || myState == State .GOTO_2
112
+ || myState == State .CALL_CLOSE ) {
113
+ myState = State .LOAD_RESOURCE ;
114
+ } else if (myState == State .STORE_ADDITIONAL_EXCEPTION ) {
115
+ myState = State .LOAD_INITIAL_EXCEPTION ;
116
+ } else if (myState == State .LOAD_INITIAL_EXCEPTION ) {
117
+ myState = State .LOAD_ADDITIONAL_EXCEPTION ;
118
+ } else if (myState == State .CALL_ADD_SUPPRESSED ) {
119
+ myState = State .LOAD_INITIAL_EXCEPTION_2 ;
120
+ } else {
121
+ setHasInstructions ();
122
+ myState = State .INITIAL ;
123
+ }
108
124
} else {
109
- myState = State .INITIAL ;
110
125
setHasInstructions ();
126
+ myState = State .INITIAL ;
111
127
}
112
128
}
113
129
@@ -125,8 +141,8 @@ public void visitJumpInsn(int opcode, Label label) {
125
141
} else if (myState == State .CALL_ADD_SUPPRESSED && opcode == Opcodes .GOTO ) {
126
142
myState = State .GOTO_2 ;
127
143
} else {
128
- myState = State .INITIAL ;
129
144
setHasInstructions ();
145
+ myState = State .INITIAL ;
130
146
}
131
147
}
132
148
@@ -135,24 +151,19 @@ public void visitMethodInsn(int opcode, String owner, String name, String descri
135
151
mv .visitMethodInsn (opcode , owner , name , descriptor , isInterface );
136
152
if ((opcode == Opcodes .INVOKEINTERFACE || opcode == Opcodes .INVOKEVIRTUAL )
137
153
&& "close" .equals (name )
138
- && "()V" .equals (descriptor )) {
139
- if (myState == State .LOAD_RESOURCE ) {
140
- myState = State .CALL_CLOSE ;
141
- return ;
142
- } else if (myState == State .LOAD_INITIAL_EXCEPTION_2 ) {
143
- myState = State .CALL_CLOSE_2 ;
144
- return ;
145
- }
154
+ && "()V" .equals (descriptor )
155
+ && myState == State .LOAD_RESOURCE ) {
156
+ myState = State .CALL_CLOSE ;
146
157
} else if (myState == State .LOAD_ADDITIONAL_EXCEPTION
147
158
&& opcode == Opcodes .INVOKEVIRTUAL
148
159
&& "java/lang/Throwable" .equals (owner )
149
160
&& "addSuppressed" .equals (name )
150
161
&& "(Ljava/lang/Throwable;)V" .equals (descriptor )) {
151
162
myState = State .CALL_ADD_SUPPRESSED ;
152
- return ;
163
+ } else {
164
+ setHasInstructions ();
165
+ myState = State .INITIAL ;
153
166
}
154
- myState = State .INITIAL ;
155
- setHasInstructions ();
156
167
}
157
168
158
169
@ Override
@@ -161,8 +172,8 @@ public void visitInsn(int opcode) {
161
172
if (myState == State .LOAD_INITIAL_EXCEPTION_2 && opcode == Opcodes .ATHROW ) {
162
173
myState = State .THROW ;
163
174
} else {
164
- myState = State .INITIAL ;
165
175
setHasInstructions ();
176
+ myState = State .INITIAL ;
166
177
}
167
178
}
168
179
}
0 commit comments