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  public class NewHandler extends AbstractExpressionHandler {
30  
31      
32      private final DetailAST mainAst;
33  
34      
35  
36  
37  
38  
39  
40  
41  
42      public NewHandler(IndentationCheck indentCheck,
43                        DetailAST ast,
44                        AbstractExpressionHandler parent) {
45          super(indentCheck, "new", ast, parent);
46          mainAst = ast;
47      }
48  
49      @Override
50      public void checkIndentation() {
51          
52          if (isOnStartOfLine(mainAst)) {
53              final int columnNo = expandedTabsColumnNo(mainAst);
54              final IndentLevel level = getIndentImpl();
55  
56              final boolean forceStrictCondition = getIndentCheck().isForceStrictCondition();
57              if (forceStrictCondition && !level.isAcceptable(columnNo)
58                  || !forceStrictCondition && level.isGreaterThan(columnNo)) {
59                  logError(mainAst, "", columnNo, level);
60              }
61          }
62  
63          final DetailAST firstChild = mainAst.getFirstChild();
64          if (firstChild != null) {
65              checkExpressionSubtree(firstChild, getIndent(), false, false);
66          }
67  
68          final DetailAST expression = mainAst.findFirstToken(TokenTypes.ELIST);
69          if (checkNestedNew(expression) && isOnStartOfLine(expression)) {
70              final IndentLevel indentLevel = new IndentLevel(getIndent(),
71                      getLineWrappingIndent());
72              checkExpressionSubtree(expression, indentLevel, false, false);
73          }
74  
75          final DetailAST lparen = mainAst.findFirstToken(TokenTypes.LPAREN);
76          checkLeftParen(lparen);
77      }
78  
79      
80  
81  
82  
83  
84  
85  
86      public boolean checkNestedNew(DetailAST expression) {
87          boolean result = false;
88          if (expression != null && expression.getFirstChild() != null) {
89              final boolean isNestedNewPresent = expression.getFirstChild()
90                  .findFirstToken(TokenTypes.LITERAL_NEW) != null;
91              if (!isNestedNewPresent) {
92                  result = true;
93              }
94          }
95          return result;
96      }
97  
98      @Override
99      public IndentLevel getSuggestedChildIndent(AbstractExpressionHandler child) {
100         final int offset;
101         if (TokenUtil.isOfType(child.getMainAst(), TokenTypes.OBJBLOCK)) {
102             offset = getBasicOffset();
103         }
104         else {
105             offset = getLineWrappingIndent();
106         }
107         return new IndentLevel(getIndent(), offset);
108     }
109 
110     @Override
111     protected IndentLevel getIndentImpl() {
112         IndentLevel result;
113         
114         
115         if (getLineStart(mainAst) == mainAst.getColumnNo()) {
116             result = super.getIndentImpl();
117 
118             final boolean isLineWrappedNew = TokenUtil.isOfType(mainAst.getParent().getParent(),
119                                         TokenTypes.ASSIGN, TokenTypes.LITERAL_RETURN);
120 
121             if (isLineWrappedNew || doesChainedMethodNeedsLineWrapping()) {
122                 result = new IndentLevel(result, getLineWrappingIndent());
123             }
124         }
125         else {
126             result = new IndentLevel(getLineStart(mainAst));
127         }
128 
129         return result;
130     }
131 
132     
133 
134 
135 
136 
137 
138     private int getLineWrappingIndent() {
139         return getIndentCheck().getLineWrappingIndentation();
140     }
141 
142     @Override
143     protected boolean shouldIncreaseIndent() {
144         return false;
145     }
146 
147     
148 
149 
150 
151 
152 
153 
154     private boolean doesChainedMethodNeedsLineWrapping() {
155         DetailAST ast = mainAst.getParent();
156 
157         while (TokenUtil.isOfType(ast, TokenTypes.DOT, TokenTypes.METHOD_CALL, TokenTypes.EXPR)) {
158             ast = ast.getParent();
159         }
160 
161         return TokenUtil.isOfType(ast, TokenTypes.ASSIGN, TokenTypes.LITERAL_RETURN);
162     }
163 
164 }