View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2026 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ///////////////////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.checks.coding;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck.MSG_KEY;
24  
25  import java.io.File;
26  import java.util.Optional;
27  import java.util.function.Predicate;
28  
29  import org.junit.jupiter.api.Test;
30  
31  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
32  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
33  import com.puppycrawl.tools.checkstyle.JavaParser;
34  import com.puppycrawl.tools.checkstyle.api.DetailAST;
35  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
36  import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
37  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
38  
39  public class HiddenFieldCheckTest
40      extends AbstractModuleTestSupport {
41  
42      @Override
43      public String getPackageLocation() {
44          return "com/puppycrawl/tools/checkstyle/checks/coding/hiddenfield";
45      }
46  
47      @Test
48      public void testStaticVisibilityFromLambdas() throws Exception {
49          final String[] expected = {
50              "31:34: " + getCheckMessage(MSG_KEY, "value"),
51              "64:31: " + getCheckMessage(MSG_KEY, "languageCode"),
52              "74:35: " + getCheckMessage(MSG_KEY, "number"),
53              "87:35: " + getCheckMessage(MSG_KEY, "id"),
54              "115:33: " + getCheckMessage(MSG_KEY, "note"),
55              "141:48: " + getCheckMessage(MSG_KEY, "stringValue"),
56              "141:69: " + getCheckMessage(MSG_KEY, "intValue"),
57              "155:69: " + getCheckMessage(MSG_KEY, "doubleValue"),
58              "168:51: " + getCheckMessage(MSG_KEY, "firstString"),
59              "168:64: " + getCheckMessage(MSG_KEY, "secondString"),
60              "187:49: " + getCheckMessage(MSG_KEY, "first"),
61              "214:62: " + getCheckMessage(MSG_KEY, "mPi"),
62              "231:27: " + getCheckMessage(MSG_KEY, "justSomeList"),
63              "231:61: " + getCheckMessage(MSG_KEY, "justSomeMap"),
64              "246:55: " + getCheckMessage(MSG_KEY, "someObject"),
65              "255:52: " + getCheckMessage(MSG_KEY, "someObject"),
66          };
67          verifyWithInlineConfigParser(
68                  getPath("InputHiddenFieldLambdas.java"), expected);
69      }
70  
71      @Test
72      public void testStaticVisibilityFromAnonymousClasses() throws Exception {
73          final String[] expected = {
74              "22:45: " + getCheckMessage(MSG_KEY, "other"),
75              "28:42: " + getCheckMessage(MSG_KEY, "other"),
76              "36:49: " + getCheckMessage(MSG_KEY, "other"),
77              "46:53: " + getCheckMessage(MSG_KEY, "other"),
78              "58:26: " + getCheckMessage(MSG_KEY, "someField"),
79          };
80          verifyWithInlineConfigParser(
81                  getPath("InputHiddenFieldStaticVisibility.java"), expected);
82      }
83  
84      @Test
85      public void testHiddenFieldBasic() throws Exception {
86          final String[] expected = {
87              "21:13: " + getCheckMessage(MSG_KEY, "hidden"),
88              "30:13: " + getCheckMessage(MSG_KEY, "hidden"),
89              "35:18: " + getCheckMessage(MSG_KEY, "hidden"),
90              "50:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
91              "59:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
92              "60:17: " + getCheckMessage(MSG_KEY, "hidden"),
93              "65:22: " + getCheckMessage(MSG_KEY, "innerHidden"),
94              "69:22: " + getCheckMessage(MSG_KEY, "hidden"),
95              "81:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
96              "82:17: " + getCheckMessage(MSG_KEY, "hidden"),
97              "87:13: " + getCheckMessage(MSG_KEY, "hidden"),
98          };
99          verifyWithInlineConfigParser(
100                  getPath("InputHiddenFieldBasic.java"), expected);
101     }
102 
103     @Test
104     public void testHiddenFieldInterface() throws Exception {
105         final String[] expected = {
106         };
107         verifyWithInlineConfigParser(
108                  getPath("InputHiddenFieldInterface.java"), expected);
109     }
110 
111     @Test
112     public void testHiddenFieldStatic() throws Exception {
113         final String[] expected = {
114             "22:13: " + getCheckMessage(MSG_KEY, "hidden"),
115             "27:13: " + getCheckMessage(MSG_KEY, "hidden"),
116             "32:13: " + getCheckMessage(MSG_KEY, "hidden"),
117             "36:13: " + getCheckMessage(MSG_KEY, "hidden"),
118 
119         };
120         verifyWithInlineConfigParser(
121                  getPath("InputHiddenFieldStatic.java"), expected);
122     }
123 
124     @Test
125     public void testHiddenFieldPropertySetter() throws Exception {
126         final String[] expected = {
127         };
128         verifyWithInlineConfigParser(
129                  getPath("InputHiddenFieldPropertySetter.java"), expected);
130     }
131 
132     @Test
133     public void testHiddenFieldEnum() throws Exception {
134         final String[] expected = {
135             "30:17: " + getCheckMessage(MSG_KEY, "hidden"),
136             "47:13: " + getCheckMessage(MSG_KEY, "hidden"),
137             "53:13: " + getCheckMessage(MSG_KEY, "hiddenStatic"),
138         };
139         verifyWithInlineConfigParser(
140                  getPath("InputHiddenFieldEnum.java"), expected);
141     }
142 
143     @Test
144     public void testHiddenFieldMisc() throws Exception {
145         final String[] expected = {
146         };
147         verifyWithInlineConfigParser(
148                  getPath("InputHiddenFieldMisc.java"), expected);
149     }
150 
151     @Test
152     public void testHiddenField2Basic() throws Exception {
153         final String[] expected = {
154             "21:13: " + getCheckMessage(MSG_KEY, "hidden"),
155             "24:39: " + getCheckMessage(MSG_KEY, "hidden"),
156             "31:13: " + getCheckMessage(MSG_KEY, "hidden"),
157             "36:18: " + getCheckMessage(MSG_KEY, "hidden"),
158             "41:33: " + getCheckMessage(MSG_KEY, "hidden"),
159             "52:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
160             "55:26: " + getCheckMessage(MSG_KEY, "innerHidden"),
161             "61:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
162             "62:17: " + getCheckMessage(MSG_KEY, "hidden"),
163             "67:22: " + getCheckMessage(MSG_KEY, "innerHidden"),
164             "71:22: " + getCheckMessage(MSG_KEY, "hidden"),
165             "76:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
166             "78:17: " + getCheckMessage(MSG_KEY, "hidden"),
167             "84:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
168             "85:17: " + getCheckMessage(MSG_KEY, "hidden"),
169             "90:13: " + getCheckMessage(MSG_KEY, "hidden"),
170         };
171         verifyWithInlineConfigParser(
172                  getPath("InputHiddenField2Basic.java"), expected);
173     }
174 
175     @Test
176     public void testHiddenField2Interface() throws Exception {
177         final String[] expected = {
178         };
179         verifyWithInlineConfigParser(
180                  getPath("InputHiddenField2Interface.java"), expected);
181     }
182 
183     @Test
184     public void testHiddenField2Static() throws Exception {
185         final String[] expected = {
186             "22:13: " + getCheckMessage(MSG_KEY, "hidden"),
187             "27:13: " + getCheckMessage(MSG_KEY, "hidden"),
188             "32:13: " + getCheckMessage(MSG_KEY, "hidden"),
189             "36:13: " + getCheckMessage(MSG_KEY, "hidden"),
190             "63:23: " + getCheckMessage(MSG_KEY, "y"),
191         };
192         verifyWithInlineConfigParser(
193                  getPath("InputHiddenField2Static.java"), expected);
194     }
195 
196     @Test
197     public void testHiddenField2PropertySetter() throws Exception {
198         final String[] expected = {
199             "21:29: " + getCheckMessage(MSG_KEY, "prop"),
200             "27:29: " + getCheckMessage(MSG_KEY, "prop"),
201             "33:29: " + getCheckMessage(MSG_KEY, "prop"),
202             "45:28: " + getCheckMessage(MSG_KEY, "prop"),
203             "64:41: " + getCheckMessage(MSG_KEY, "prop"),
204             "78:29: " + getCheckMessage(MSG_KEY, "prop"),
205             "89:42: " + getCheckMessage(MSG_KEY, "prop2"),
206         };
207         verifyWithInlineConfigParser(
208                  getPath("InputHiddenField2PropertySetter.java"), expected);
209     }
210 
211     @Test
212     public void testHiddenField2Enum() throws Exception {
213         final String[] expected = {
214             "30:17: " + getCheckMessage(MSG_KEY, "hidden"),
215             "40:31: " + getCheckMessage(MSG_KEY, "hidden"),
216             "47:13: " + getCheckMessage(MSG_KEY, "hidden"),
217             "53:13: " + getCheckMessage(MSG_KEY, "hiddenStatic"),
218         };
219         verifyWithInlineConfigParser(
220                  getPath("InputHiddenField2Enum.java"), expected);
221     }
222 
223     @Test
224     public void testHiddenField2Misc() throws Exception {
225         final String[] expected = {
226             "19:45: " + getCheckMessage(MSG_KEY, "x"),
227             "24:34: " + getCheckMessage(MSG_KEY, "xAxis"),
228             "31:23: " + getCheckMessage(MSG_KEY, "i"),
229         };
230         verifyWithInlineConfigParser(
231                  getPath("InputHiddenField2Misc.java"), expected);
232     }
233 
234     /** Tests ignoreFormat property. */
235     @Test
236     public void testIgnoreFormat()
237             throws Exception {
238         final DefaultConfiguration checkConfig =
239             createModuleConfig(HiddenFieldCheck.class);
240         checkConfig.addProperty("ignoreFormat", "^i.*$");
241         assertWithMessage("Ignore format should not be null")
242             .that(checkConfig.getProperty("ignoreFormat"))
243             .isNotNull();
244         final String[] expected = {
245             "30:13: " + getCheckMessage(MSG_KEY, "hidden"),
246             "33:34: " + getCheckMessage(MSG_KEY, "hidden"),
247             "40:13: " + getCheckMessage(MSG_KEY, "hidden"),
248             "45:18: " + getCheckMessage(MSG_KEY, "hidden"),
249             "50:33: " + getCheckMessage(MSG_KEY, "hidden"),
250             "71:17: " + getCheckMessage(MSG_KEY, "hidden"),
251             "79:22: " + getCheckMessage(MSG_KEY, "hidden"),
252             "85:17: " + getCheckMessage(MSG_KEY, "hidden"),
253             "92:17: " + getCheckMessage(MSG_KEY, "hidden"),
254             "97:13: " + getCheckMessage(MSG_KEY, "hidden"),
255             "115:29: " + getCheckMessage(MSG_KEY, "prop"),
256             "121:29: " + getCheckMessage(MSG_KEY, "prop"),
257             "127:29: " + getCheckMessage(MSG_KEY, "prop"),
258             "139:28: " + getCheckMessage(MSG_KEY, "prop"),
259             "153:13: " + getCheckMessage(MSG_KEY, "hidden"),
260             "158:13: " + getCheckMessage(MSG_KEY, "hidden"),
261             "163:13: " + getCheckMessage(MSG_KEY, "hidden"),
262             "167:13: " + getCheckMessage(MSG_KEY, "hidden"),
263             "194:23: " + getCheckMessage(MSG_KEY, "y"),
264             "215:17: " + getCheckMessage(MSG_KEY, "hidden"),
265             "225:22: " + getCheckMessage(MSG_KEY, "hidden"),
266             "232:13: " + getCheckMessage(MSG_KEY, "hidden"),
267             "238:13: " + getCheckMessage(MSG_KEY, "hiddenStatic"),
268             "245:41: " + getCheckMessage(MSG_KEY, "x"),
269             "251:30: " + getCheckMessage(MSG_KEY, "xAxis"),
270             "268:41: " + getCheckMessage(MSG_KEY, "prop"),
271             "282:29: " + getCheckMessage(MSG_KEY, "prop"),
272             "293:42: " + getCheckMessage(MSG_KEY, "prop2"),
273         };
274         verifyWithInlineConfigParser(
275                 getPath("InputHiddenField3.java"), expected);
276     }
277 
278     /** Tests ignoreSetter property. */
279     @Test
280     public void testIgnoreSetter()
281             throws Exception {
282         final String[] expected = {
283             "30:13: " + getCheckMessage(MSG_KEY, "hidden"),
284             "33:34: " + getCheckMessage(MSG_KEY, "hidden"),
285             "40:13: " + getCheckMessage(MSG_KEY, "hidden"),
286             "45:18: " + getCheckMessage(MSG_KEY, "hidden"),
287             "50:33: " + getCheckMessage(MSG_KEY, "hidden"),
288             "61:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
289             "64:26: " + getCheckMessage(MSG_KEY, "innerHidden"),
290             "70:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
291             "71:17: " + getCheckMessage(MSG_KEY, "hidden"),
292             "76:22: " + getCheckMessage(MSG_KEY, "innerHidden"),
293             "80:22: " + getCheckMessage(MSG_KEY, "hidden"),
294             "85:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
295             "87:17: " + getCheckMessage(MSG_KEY, "hidden"),
296             "93:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
297             "94:17: " + getCheckMessage(MSG_KEY, "hidden"),
298             "99:13: " + getCheckMessage(MSG_KEY, "hidden"),
299             "123:29: " + getCheckMessage(MSG_KEY, "prop"),
300             "129:29: " + getCheckMessage(MSG_KEY, "prop"),
301             "141:28: " + getCheckMessage(MSG_KEY, "prop"),
302             "155:13: " + getCheckMessage(MSG_KEY, "hidden"),
303             "160:13: " + getCheckMessage(MSG_KEY, "hidden"),
304             "165:13: " + getCheckMessage(MSG_KEY, "hidden"),
305             "169:13: " + getCheckMessage(MSG_KEY, "hidden"),
306             "196:23: " + getCheckMessage(MSG_KEY, "y"),
307             "217:17: " + getCheckMessage(MSG_KEY, "hidden"),
308             "227:22: " + getCheckMessage(MSG_KEY, "hidden"),
309             "234:13: " + getCheckMessage(MSG_KEY, "hidden"),
310             "240:13: " + getCheckMessage(MSG_KEY, "hiddenStatic"),
311             "247:41: " + getCheckMessage(MSG_KEY, "x"),
312             "270:41: " + getCheckMessage(MSG_KEY, "prop"),
313             "295:42: " + getCheckMessage(MSG_KEY, "prop2"),
314         };
315         verifyWithInlineConfigParser(
316                 getPath("InputHiddenField4.java"), expected);
317     }
318 
319     /** Tests ignoreSetter and setterCanReturnItsClass properties. */
320     @Test
321     public void testIgnoreChainSetter()
322             throws Exception {
323         final String[] expected = {
324             "30:13: " + getCheckMessage(MSG_KEY, "hidden"),
325             "33:34: " + getCheckMessage(MSG_KEY, "hidden"),
326             "40:13: " + getCheckMessage(MSG_KEY, "hidden"),
327             "45:18: " + getCheckMessage(MSG_KEY, "hidden"),
328             "50:33: " + getCheckMessage(MSG_KEY, "hidden"),
329             "61:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
330             "64:26: " + getCheckMessage(MSG_KEY, "innerHidden"),
331             "70:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
332             "71:17: " + getCheckMessage(MSG_KEY, "hidden"),
333             "76:22: " + getCheckMessage(MSG_KEY, "innerHidden"),
334             "80:22: " + getCheckMessage(MSG_KEY, "hidden"),
335             "85:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
336             "87:17: " + getCheckMessage(MSG_KEY, "hidden"),
337             "93:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
338             "94:17: " + getCheckMessage(MSG_KEY, "hidden"),
339             "99:13: " + getCheckMessage(MSG_KEY, "hidden"),
340             "123:29: " + getCheckMessage(MSG_KEY, "prop"),
341             "129:29: " + getCheckMessage(MSG_KEY, "prop"),
342             "141:28: " + getCheckMessage(MSG_KEY, "prop"),
343             "155:13: " + getCheckMessage(MSG_KEY, "hidden"),
344             "160:13: " + getCheckMessage(MSG_KEY, "hidden"),
345             "165:13: " + getCheckMessage(MSG_KEY, "hidden"),
346             "169:13: " + getCheckMessage(MSG_KEY, "hidden"),
347             "196:23: " + getCheckMessage(MSG_KEY, "y"),
348             "217:17: " + getCheckMessage(MSG_KEY, "hidden"),
349             "227:22: " + getCheckMessage(MSG_KEY, "hidden"),
350             "234:13: " + getCheckMessage(MSG_KEY, "hidden"),
351             "240:13: " + getCheckMessage(MSG_KEY, "hiddenStatic"),
352             "247:41: " + getCheckMessage(MSG_KEY, "x"),
353         };
354         verifyWithInlineConfigParser(
355                 getPath("InputHiddenField5.java"), expected);
356     }
357 
358     /** Tests ignoreConstructorParameter property. */
359     @Test
360     public void testIgnoreConstructorParameter()
361             throws Exception {
362         final String[] expected = {
363             "29:13: " + getCheckMessage(MSG_KEY, "hidden"),
364             "38:13: " + getCheckMessage(MSG_KEY, "hidden"),
365             "43:18: " + getCheckMessage(MSG_KEY, "hidden"),
366             "48:33: " + getCheckMessage(MSG_KEY, "hidden"),
367             "59:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
368             "68:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
369             "69:17: " + getCheckMessage(MSG_KEY, "hidden"),
370             "74:22: " + getCheckMessage(MSG_KEY, "innerHidden"),
371             "78:22: " + getCheckMessage(MSG_KEY, "hidden"),
372             "83:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
373             "85:17: " + getCheckMessage(MSG_KEY, "hidden"),
374             "91:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
375             "92:17: " + getCheckMessage(MSG_KEY, "hidden"),
376             "97:13: " + getCheckMessage(MSG_KEY, "hidden"),
377             "115:29: " + getCheckMessage(MSG_KEY, "prop"),
378             "121:29: " + getCheckMessage(MSG_KEY, "prop"),
379             "127:29: " + getCheckMessage(MSG_KEY, "prop"),
380             "139:28: " + getCheckMessage(MSG_KEY, "prop"),
381             "153:13: " + getCheckMessage(MSG_KEY, "hidden"),
382             "158:13: " + getCheckMessage(MSG_KEY, "hidden"),
383             "163:13: " + getCheckMessage(MSG_KEY, "hidden"),
384             "167:13: " + getCheckMessage(MSG_KEY, "hidden"),
385             "194:23: " + getCheckMessage(MSG_KEY, "y"),
386             "215:17: " + getCheckMessage(MSG_KEY, "hidden"),
387             "232:13: " + getCheckMessage(MSG_KEY, "hidden"),
388             "238:13: " + getCheckMessage(MSG_KEY, "hiddenStatic"),
389             "245:41: " + getCheckMessage(MSG_KEY, "x"),
390             "251:30: " + getCheckMessage(MSG_KEY, "xAxis"),
391             "268:41: " + getCheckMessage(MSG_KEY, "prop"),
392             "282:29: " + getCheckMessage(MSG_KEY, "prop"),
393             "293:42: " + getCheckMessage(MSG_KEY, "prop2"),
394             "305:19: " + getCheckMessage(MSG_KEY, "i"),
395         };
396         verifyWithInlineConfigParser(
397                 getPath("InputHiddenField6.java"), expected);
398     }
399 
400     /** Test against a class with field declarations in different order. */
401     @Test
402     public void testReordered()
403             throws Exception {
404         final String[] expected = {
405             "30:13: " + getCheckMessage(MSG_KEY, "hidden"),
406             "33:40: " + getCheckMessage(MSG_KEY, "hidden"),
407             "40:13: " + getCheckMessage(MSG_KEY, "hidden"),
408             "45:18: " + getCheckMessage(MSG_KEY, "hidden"),
409             "50:33: " + getCheckMessage(MSG_KEY, "hidden"),
410             "61:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
411             "64:26: " + getCheckMessage(MSG_KEY, "innerHidden"),
412             "70:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
413             "71:17: " + getCheckMessage(MSG_KEY, "hidden"),
414             "76:22: " + getCheckMessage(MSG_KEY, "innerHidden"),
415             "80:22: " + getCheckMessage(MSG_KEY, "hidden"),
416             "85:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
417             "87:17: " + getCheckMessage(MSG_KEY, "hidden"),
418             "93:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
419             "94:17: " + getCheckMessage(MSG_KEY, "hidden"),
420             "100:13: " + getCheckMessage(MSG_KEY, "hidden"),
421             "122:17: " + getCheckMessage(MSG_KEY, "hidden"),
422             "135:21: " + getCheckMessage(MSG_KEY, "hidden"),
423             "142:13: " + getCheckMessage(MSG_KEY, "hidden"),
424             "148:13: " + getCheckMessage(MSG_KEY, "hiddenStatic"),
425         };
426         verifyWithInlineConfigParser(
427                 getPath("InputHiddenFieldReorder.java"), expected);
428     }
429 
430     @Test
431     public void testIgnoreAbstractMethods() throws Exception {
432 
433         final String[] expected = {
434             "30:13: " + getCheckMessage(MSG_KEY, "hidden"),
435             "33:34: " + getCheckMessage(MSG_KEY, "hidden"),
436             "40:13: " + getCheckMessage(MSG_KEY, "hidden"),
437             "45:18: " + getCheckMessage(MSG_KEY, "hidden"),
438             "50:33: " + getCheckMessage(MSG_KEY, "hidden"),
439             "61:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
440             "64:26: " + getCheckMessage(MSG_KEY, "innerHidden"),
441             "70:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
442             "71:17: " + getCheckMessage(MSG_KEY, "hidden"),
443             "76:22: " + getCheckMessage(MSG_KEY, "innerHidden"),
444             "80:22: " + getCheckMessage(MSG_KEY, "hidden"),
445             "85:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
446             "87:17: " + getCheckMessage(MSG_KEY, "hidden"),
447             "93:17: " + getCheckMessage(MSG_KEY, "innerHidden"),
448             "94:17: " + getCheckMessage(MSG_KEY, "hidden"),
449             "99:13: " + getCheckMessage(MSG_KEY, "hidden"),
450             "117:29: " + getCheckMessage(MSG_KEY, "prop"),
451             "123:29: " + getCheckMessage(MSG_KEY, "prop"),
452             "129:29: " + getCheckMessage(MSG_KEY, "prop"),
453             "141:28: " + getCheckMessage(MSG_KEY, "prop"),
454             "155:13: " + getCheckMessage(MSG_KEY, "hidden"),
455             "160:13: " + getCheckMessage(MSG_KEY, "hidden"),
456             "165:13: " + getCheckMessage(MSG_KEY, "hidden"),
457             "169:13: " + getCheckMessage(MSG_KEY, "hidden"),
458             "196:23: " + getCheckMessage(MSG_KEY, "y"),
459             "217:17: " + getCheckMessage(MSG_KEY, "hidden"),
460             "227:22: " + getCheckMessage(MSG_KEY, "hidden"),
461             "234:13: " + getCheckMessage(MSG_KEY, "hidden"),
462             "240:13: " + getCheckMessage(MSG_KEY, "hiddenStatic"),
463             "253:30: " + getCheckMessage(MSG_KEY, "xAxis"),
464             "270:41: " + getCheckMessage(MSG_KEY, "prop"),
465             "284:29: " + getCheckMessage(MSG_KEY, "prop"),
466             "295:42: " + getCheckMessage(MSG_KEY, "prop2"),
467             "307:19: " + getCheckMessage(MSG_KEY, "i"),
468         };
469         verifyWithInlineConfigParser(
470                 getPath("InputHiddenField7.java"), expected);
471     }
472 
473     @Test
474     public void testReceiverParameter() throws Exception {
475         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
476         verifyWithInlineConfigParser(
477                 getPath("InputHiddenFieldReceiver.java"), expected);
478     }
479 
480     @Test
481     public void testHiddenFieldEnhancedInstanceof() throws Exception {
482 
483         final String[] expected = {
484             "26:39: " + getCheckMessage(MSG_KEY, "price"),
485             "37:35: " + getCheckMessage(MSG_KEY, "hiddenStaticField"),
486         };
487         verifyWithInlineConfigParser(
488                 getPath("InputHiddenFieldEnhancedInstanceof.java"), expected);
489     }
490 
491     @Test
492     public void testHiddenFieldSwitchExpression() throws Exception {
493 
494         final String[] expected = {
495             "28:13: " + getCheckMessage(MSG_KEY, "x"),
496             "32:30: " + getCheckMessage(MSG_KEY, "word"),
497             "33:35: " + getCheckMessage(MSG_KEY, "otherWord"),
498             "35:21: " + getCheckMessage(MSG_KEY, "y"),
499             "39:21: " + getCheckMessage(MSG_KEY, "z"),
500             "43:21: " + getCheckMessage(MSG_KEY, "a"),
501             "47:21: " + getCheckMessage(MSG_KEY, "b"),
502             "54:13: " + getCheckMessage(MSG_KEY, "x"),
503             "58:30: " + getCheckMessage(MSG_KEY, "word"),
504             "59:35: " + getCheckMessage(MSG_KEY, "otherWord"),
505             "61:21: " + getCheckMessage(MSG_KEY, "y"),
506             "65:21: " + getCheckMessage(MSG_KEY, "z"),
507             "69:21: " + getCheckMessage(MSG_KEY, "a"),
508             "73:21: " + getCheckMessage(MSG_KEY, "b"),
509         };
510         verifyWithInlineConfigParser(
511                 getPath("InputHiddenFieldSwitchExpression.java"), expected);
512     }
513 
514     @Test
515     public void testHiddenFieldRecords() throws Exception {
516 
517         final String[] expected = {
518             "23:17: " + getCheckMessage(MSG_KEY, "myHiddenInt"),
519             "28:17: " + getCheckMessage(MSG_KEY, "myHiddenInt"),
520             "36:17: " + getCheckMessage(MSG_KEY, "hiddenField"),
521             "44:39: " + getCheckMessage(MSG_KEY, "hiddenStaticField"),
522             "59:39: " + getCheckMessage(MSG_KEY, "price"),
523             "68:21: " + getCheckMessage(MSG_KEY, "x"),
524             "72:20: " + getCheckMessage(MSG_KEY, "string"),
525             "82:21: " + getCheckMessage(MSG_KEY, "x"),
526             "86:20: " + getCheckMessage(MSG_KEY, "string"),
527         };
528         verifyWithInlineConfigParser(
529                 getPath("InputHiddenFieldRecords.java"), expected);
530     }
531 
532     @Test
533     public void testHiddenFieldLambdasInNestedScope() throws Exception {
534         final String[] expected = {
535             "21:34: " + getCheckMessage(MSG_KEY, "value"),
536         };
537         verifyWithInlineConfigParser(
538             getPath("InputHiddenFieldLambdas2.java"), expected);
539     }
540 
541     @Test
542     public void testClassNestedInRecord() throws Exception {
543 
544         final String[] expected = {
545             "23:26: " + getCheckMessage(MSG_KEY, "a"),
546         };
547         verifyWithInlineConfigParser(
548             getPath("InputHiddenFieldClassNestedInRecord.java"),
549             expected);
550     }
551 
552     @Test
553     public void testHiddenFieldInnerRecordsImplicitlyStatic() throws Exception {
554 
555         final String[] expected = {
556             "35:30: " + getCheckMessage(MSG_KEY, "pointer"),
557         };
558 
559         verifyWithInlineConfigParser(
560                 getPath("InputHiddenFieldInnerRecordsImplicitlyStatic.java"),
561                 expected);
562     }
563 
564     @Test
565     public void testHiddenFieldRecordsImplicitlyStaticClassComparison() throws Exception {
566 
567         final String[] expected = {
568             "46:27: " + getCheckMessage(MSG_KEY, "x"),
569         };
570 
571         verifyWithInlineConfigParser(
572                 getPath("InputHiddenFieldRecordsImplicitlyStaticClassComparison.java"),
573                 expected);
574     }
575 
576     @Test
577     public void testHiddenFieldRecordPattern() throws Exception {
578 
579         final String[] expected = {
580             "24:46: " + getCheckMessage(MSG_KEY, "s"),
581             "24:53: " + getCheckMessage(MSG_KEY, "x"),
582             "32:39: " + getCheckMessage(MSG_KEY, "s"),
583             "32:46: " + getCheckMessage(MSG_KEY, "x"),
584             "41:45: " + getCheckMessage(MSG_KEY, "s"),
585             "41:52: " + getCheckMessage(MSG_KEY, "x"),
586             "41:63: " + getCheckMessage(MSG_KEY, "z"),
587             "49:37: " + getCheckMessage(MSG_KEY, "s"),
588             "49:44: " + getCheckMessage(MSG_KEY, "x"),
589         };
590         verifyWithInlineConfigParser(
591                 getPath("InputHiddenFieldRecordPattern.java"), expected);
592     }
593 
594     /**
595      * We cannot reproduce situation when visitToken is called and leaveToken is not.
596      * So, we have to use reflection to be sure that even in such situation
597      * state of the field will be cleared.
598      *
599      * @throws Exception when code tested throws exception
600      */
601     @Test
602     public void testClearState() throws Exception {
603         final HiddenFieldCheck check = new HiddenFieldCheck();
604         final DetailAST root = JavaParser.parseFile(new File(getPath("InputHiddenField8.java")),
605                 JavaParser.Options.WITHOUT_COMMENTS);
606         final Optional<DetailAST> classDef = TestUtil.findTokenInAstByPredicate(root,
607             ast -> ast.getType() == TokenTypes.CLASS_DEF);
608 
609         assertWithMessage("Ast should contain CLASS_DEF")
610                 .that(classDef.isPresent())
611                 .isTrue();
612         assertWithMessage("State is not cleared on beginTree")
613                 .that(
614                     TestUtil.isStatefulFieldClearedDuringBeginTree(check, classDef.orElseThrow(),
615                         "frame", new CheckIfStatefulFieldCleared()))
616                 .isTrue();
617     }
618 
619     private static final class CheckIfStatefulFieldCleared implements Predicate<Object> {
620 
621         @Override
622         public boolean test(Object frame) {
623             boolean result = frame != null;
624 
625             // verify object is cleared
626             if (result
627                     && (TestUtil.getInternalState(frame, "parent", Boolean.class) != null
628                         || !TestUtil.<Boolean>getInternalState(frame, "staticType", Boolean.class)
629                         || TestUtil.getInternalState(frame, "frameName", Boolean.class) != null)) {
630                 result = false;
631             }
632 
633             return result;
634         }
635 
636     }
637 
638 }