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 import com.puppycrawl.tools.checkstyle.utils.TokenUtil;
25
26
27
28
29
30 public class LambdaHandler extends AbstractExpressionHandler {
31
32
33
34
35
36
37 private boolean isLambdaCorrectlyIndented = true;
38
39
40
41
42
43
44
45
46
47 public LambdaHandler(IndentationCheck indentCheck,
48 DetailAST ast, AbstractExpressionHandler parent) {
49 super(indentCheck, "lambda", ast, parent);
50 }
51
52 @Override
53 public IndentLevel getSuggestedChildIndent(AbstractExpressionHandler child) {
54 IndentLevel childIndent = getIndent();
55 if (isLambdaCorrectlyIndented) {
56
57
58
59
60
61
62 childIndent = IndentLevel.addAcceptable(childIndent, getLineStart(getMainAst()));
63
64 if (child instanceof SlistHandler) {
65
66 childIndent = IndentLevel.addAcceptable(childIndent,
67 getLineStart(getMainAst().getFirstChild()));
68 }
69 else {
70
71
72
73 childIndent = new IndentLevel(childIndent,
74 getIndentCheck().getLineWrappingIndentation());
75 }
76 }
77
78 return childIndent;
79 }
80
81
82
83
84
85
86
87
88 @Override
89 protected IndentLevel getIndentImpl() {
90 if (getParent() instanceof MethodCallHandler) {
91 return getParent().getSuggestedChildIndent(this);
92 }
93
94 DetailAST parent = getMainAst().getParent();
95 if (getParent() instanceof NewHandler) {
96 parent = parent.getParent();
97 }
98
99
100 IndentLevel level = new IndentLevel(getLineStart(parent));
101
102
103
104 final DetailAST firstChild = getMainAst().getFirstChild();
105 if (getLineStart(firstChild) == expandedTabsColumnNo(firstChild)) {
106 level = new IndentLevel(level, getIndentCheck().getLineWrappingIndentation());
107 }
108
109 return level;
110 }
111
112 @Override
113 public void checkIndentation() {
114 final DetailAST mainAst = getMainAst();
115 final DetailAST firstChild = mainAst.getFirstChild();
116
117
118
119 final boolean isSwitchRuleLambda = firstChild == null;
120
121 if (!isSwitchRuleLambda
122 && getLineStart(firstChild) == expandedTabsColumnNo(firstChild)) {
123 final int firstChildColumnNo = expandedTabsColumnNo(firstChild);
124 final IndentLevel level = getIndent();
125
126 if (isNonAcceptableIndent(firstChildColumnNo, level)) {
127 isLambdaCorrectlyIndented = false;
128 logError(firstChild, "arguments", firstChildColumnNo, level);
129 }
130 }
131
132
133 final int mainAstColumnNo = expandedTabsColumnNo(mainAst);
134 final boolean isLineWrappedLambda = mainAstColumnNo == getLineStart(mainAst);
135 if (isLineWrappedLambda) {
136 checkLineWrappedLambda(isSwitchRuleLambda, mainAstColumnNo);
137 }
138
139 final DetailAST nextSibling = mainAst.getNextSibling();
140
141 if (isSwitchRuleLambda
142 && nextSibling.getType() == TokenTypes.EXPR
143 && !TokenUtil.areOnSameLine(mainAst, nextSibling)) {
144
145
146
147 checkSingleStatementSwitchRuleIndentation(isLineWrappedLambda);
148 }
149 }
150
151
152
153
154
155
156
157
158 private boolean isNonAcceptableIndent(int astColumnNo, IndentLevel level) {
159 return astColumnNo < level.getFirstIndentLevel()
160 || getIndentCheck().isForceStrictCondition()
161 && !level.isAcceptable(astColumnNo);
162 }
163
164
165
166
167
168
169
170
171 private void checkLineWrappedLambda(final boolean isSwitchRuleLambda,
172 final int mainAstColumnNo) {
173 final IndentLevel level;
174 final DetailAST mainAst = getMainAst();
175
176 if (isSwitchRuleLambda) {
177
178
179
180 final DetailAST previousSibling = mainAst.getPreviousSibling();
181 final int previousLineStart = getLineStart(previousSibling);
182
183 level = new IndentLevel(new IndentLevel(previousLineStart),
184 getIndentCheck().getLineWrappingIndentation());
185 }
186 else {
187 level = new IndentLevel(getIndent(),
188 getIndentCheck().getLineWrappingIndentation());
189 }
190
191 if (isNonAcceptableIndent(mainAstColumnNo, level)) {
192 isLambdaCorrectlyIndented = false;
193 logError(mainAst, "", mainAstColumnNo, level);
194 }
195 }
196
197
198
199
200
201
202
203
204
205
206
207
208
209 private void checkSingleStatementSwitchRuleIndentation(boolean isLambdaFirstInLine) {
210 final DetailAST mainAst = getMainAst();
211 IndentLevel level = getParent().getSuggestedChildIndent(this);
212
213 if (isLambdaFirstInLine) {
214
215
216 level = new IndentLevel(level, getIndentCheck().getLineWrappingIndentation());
217 }
218
219
220
221 final DetailAST nextSibling = mainAst.getNextSibling();
222 final boolean firstLineMatches = getFirstLine(nextSibling) != mainAst.getLineNo();
223 checkExpressionSubtree(nextSibling, level, firstLineMatches, false);
224 }
225 }