1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.checks;
21
22 import java.io.File;
23 import java.util.regex.Pattern;
24
25 import com.puppycrawl.tools.checkstyle.FileStatefulCheck;
26 import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
27 import com.puppycrawl.tools.checkstyle.api.DetailAST;
28 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
29 import com.puppycrawl.tools.checkstyle.utils.TokenUtil;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 @FileStatefulCheck
53 public class OuterTypeFilenameCheck extends AbstractCheck {
54
55
56
57
58
59 public static final String MSG_KEY = "type.file.mismatch";
60
61
62 private static final Pattern FILE_EXTENSION_PATTERN = Pattern.compile("\\.[^.]*$");
63
64
65 private boolean seenFirstToken;
66
67
68 private String fileName;
69
70
71 private boolean hasPublic;
72
73
74 private DetailAST wrongType;
75
76 @Override
77 public int[] getDefaultTokens() {
78 return getRequiredTokens();
79 }
80
81 @Override
82 public int[] getAcceptableTokens() {
83 return getRequiredTokens();
84 }
85
86 @Override
87 public int[] getRequiredTokens() {
88 return new int[] {
89 TokenTypes.CLASS_DEF,
90 TokenTypes.INTERFACE_DEF,
91 TokenTypes.ENUM_DEF,
92 TokenTypes.ANNOTATION_DEF,
93 TokenTypes.RECORD_DEF,
94 };
95 }
96
97 @Override
98 public void beginTree(DetailAST rootAST) {
99 fileName = getSourceFileName();
100 seenFirstToken = false;
101 hasPublic = false;
102 wrongType = null;
103 }
104
105 @Override
106 public void visitToken(DetailAST ast) {
107 if (seenFirstToken) {
108 final DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS);
109 if (modifiers.findFirstToken(TokenTypes.LITERAL_PUBLIC) != null
110 && TokenUtil.isRootNode(ast.getParent())) {
111 hasPublic = true;
112 }
113 }
114 else {
115 final String outerTypeName = ast.findFirstToken(TokenTypes.IDENT).getText();
116
117 if (!fileName.equals(outerTypeName)) {
118 wrongType = ast;
119 }
120 }
121 seenFirstToken = true;
122 }
123
124 @Override
125 public void finishTree(DetailAST rootAST) {
126 if (!hasPublic && wrongType != null) {
127 log(wrongType, MSG_KEY);
128 }
129 }
130
131
132
133
134
135
136 private String getSourceFileName() {
137 String name = getFilePath();
138 name = name.substring(name.lastIndexOf(File.separatorChar) + 1);
139 return FILE_EXTENSION_PATTERN.matcher(name).replaceAll("");
140 }
141
142 }