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 @FileStatefulCheck
40 public class OuterTypeFilenameCheck extends AbstractCheck {
41
42
43
44
45
46 public static final String MSG_KEY = "type.file.mismatch";
47
48
49 private static final Pattern FILE_EXTENSION_PATTERN = Pattern.compile("\\.[^.]*$");
50
51
52 private boolean seenFirstToken;
53
54
55 private String fileName;
56
57
58 private boolean hasPublic;
59
60
61 private DetailAST wrongType;
62
63 @Override
64 public int[] getDefaultTokens() {
65 return getRequiredTokens();
66 }
67
68 @Override
69 public int[] getAcceptableTokens() {
70 return getRequiredTokens();
71 }
72
73 @Override
74 public int[] getRequiredTokens() {
75 return new int[] {
76 TokenTypes.CLASS_DEF,
77 TokenTypes.INTERFACE_DEF,
78 TokenTypes.ENUM_DEF,
79 TokenTypes.ANNOTATION_DEF,
80 TokenTypes.RECORD_DEF,
81 };
82 }
83
84 @Override
85 public void beginTree(DetailAST rootAST) {
86 fileName = getSourceFileName();
87 seenFirstToken = false;
88 hasPublic = false;
89 wrongType = null;
90 }
91
92 @Override
93 public void visitToken(DetailAST ast) {
94 if (seenFirstToken) {
95 final DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS);
96 if (modifiers.findFirstToken(TokenTypes.LITERAL_PUBLIC) != null
97 && TokenUtil.isRootNode(ast.getParent())) {
98 hasPublic = true;
99 }
100 }
101 else {
102 final String outerTypeName = ast.findFirstToken(TokenTypes.IDENT).getText();
103
104 if (!fileName.equals(outerTypeName)) {
105 wrongType = ast;
106 }
107 }
108 seenFirstToken = true;
109 }
110
111 @Override
112 public void finishTree(DetailAST rootAST) {
113 if (!hasPublic && wrongType != null) {
114 log(wrongType, MSG_KEY);
115 }
116 }
117
118
119
120
121
122
123 private String getSourceFileName() {
124 String name = getFilePath();
125 name = name.substring(name.lastIndexOf(File.separatorChar) + 1);
126 return FILE_EXTENSION_PATTERN.matcher(name).replaceAll("");
127 }
128
129 }