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.indentation;
21
22 import com.puppycrawl.tools.checkstyle.api.DetailAST;
23 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
24
25
26
27
28
29 public class TryHandler extends BlockParentHandler {
30
31
32
33
34
35
36
37
38
39 public TryHandler(IndentationCheck indentCheck,
40 DetailAST ast, AbstractExpressionHandler parent) {
41 super(indentCheck, "try", ast, parent);
42 }
43
44
45
46
47
48
49 private DetailAST getTryResLparen() {
50 return getMainAst().getFirstChild().getFirstChild();
51 }
52
53
54
55
56
57
58 private DetailAST getTryResRparen() {
59 return getMainAst().getFirstChild().getLastChild();
60 }
61
62 @Override
63 public IndentLevel getSuggestedChildIndent(AbstractExpressionHandler child) {
64 final IndentLevel result;
65 if (child instanceof CatchHandler
66 || child instanceof FinallyHandler
67 || child instanceof NewHandler
68 && isTryBlocksResourceSpecification(child)) {
69 result = getIndent();
70 }
71 else {
72 result = super.getSuggestedChildIndent(child);
73 }
74 return result;
75 }
76
77 @Override
78 public void checkIndentation() {
79 super.checkIndentation();
80 if (getMainAst().getFirstChild().getType() == TokenTypes.RESOURCE_SPECIFICATION) {
81 checkTryResParen(getTryResLparen(), "lparen");
82 checkTryResParen(getTryResRparen(), "rparen");
83 checkTryResources(getMainAst().getFirstChild());
84 }
85 }
86
87 @Override
88 protected boolean shouldCheckIndentationForChild(DetailAST child) {
89 final DetailAST leftCurly = getLeftCurly();
90 return getFirstAstNode(child).getLineNo() != leftCurly.getLineNo();
91 }
92
93
94
95
96
97
98
99
100
101 private void checkTryResParen(final DetailAST parenAst,
102 final String subType) {
103 if (isOnStartOfLine(parenAst)) {
104 final IndentLevel expectedIdent = new IndentLevel(getIndent(), 0,
105 getIndentCheck().getLineWrappingIndentation());
106
107 checkChildIndentation(parenAst, subType, expectedIdent);
108 }
109 }
110
111
112
113
114
115
116
117
118
119
120 private void checkChildIndentation(DetailAST ast, String subType, IndentLevel expectedIdent) {
121 if (getIndentCheck().isForceStrictCondition()) {
122 if (!expectedIdent.isAcceptable(expandedTabsColumnNo(ast))) {
123 logError(ast, subType, expandedTabsColumnNo(ast), expectedIdent);
124 }
125 }
126 else {
127 if (expandedTabsColumnNo(ast) < expectedIdent.getFirstIndentLevel()) {
128 logError(ast, subType, expandedTabsColumnNo(ast), expectedIdent);
129 }
130 }
131 }
132
133
134
135
136
137
138 private void checkTryResources(final DetailAST resourcesSpecAst) {
139 final DetailAST resourcesAst = resourcesSpecAst.findFirstToken(TokenTypes.RESOURCES);
140 final int indentation = getIndent().getFirstIndentLevel()
141 + getIndentCheck().getLineWrappingIndentation();
142 final IndentLevel expectedResourceIndent = new IndentLevel(indentation);
143
144 final String subType = "resource";
145
146 DetailAST resourceAst = resourcesAst.getFirstChild();
147 while (resourceAst != null) {
148 if (resourceAst.getType() == TokenTypes.RESOURCE) {
149 final DetailAST nextSibling;
150 if (resourceAst.getNextSibling() == null) {
151 nextSibling = getTryResRparen();
152 }
153 else {
154 nextSibling = resourceAst.getNextSibling();
155 }
156 if (isOnStartOfLine(resourceAst)) {
157 checkChildIndentation(resourceAst, subType, expectedResourceIndent);
158 checkWrappingIndentation(
159 resourceAst,
160 nextSibling,
161 getIndentCheck().getLineWrappingIndentation(),
162 expectedResourceIndent.getFirstIndentLevel(),
163 true);
164 }
165 else {
166 checkWrappingIndentation(resourceAst, nextSibling);
167 }
168 }
169 resourceAst = resourceAst.getNextSibling();
170 }
171 }
172
173
174
175
176
177
178
179
180
181 private static boolean isTryBlocksResourceSpecification(AbstractExpressionHandler expression) {
182 boolean isResourceSpecificationExpression = false;
183
184 DetailAST ast = expression.getMainAst();
185
186 while (ast.getType() != TokenTypes.LITERAL_TRY) {
187 if (ast.getType() == TokenTypes.RESOURCE_SPECIFICATION) {
188 isResourceSpecificationExpression = true;
189 break;
190 }
191
192 ast = ast.getParent();
193 }
194
195 return isResourceSpecificationExpression;
196 }
197
198 }