2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 package com
.intellij
.psi
.impl
.source
.codeStyle
;
22 import com
.intellij
.lang
.ASTNode
;
23 import com
.intellij
.openapi
.fileTypes
.FileType
;
24 import com
.intellij
.openapi
.project
.Project
;
25 import com
.intellij
.psi
.impl
.source
.tree
.CompositeElement
;
26 import com
.intellij
.psi
.impl
.source
.tree
.ElementType
;
27 import com
.intellij
.psi
.impl
.source
.tree
.TreeUtil
;
29 public class JavaHelper
extends Helper
{
30 public JavaHelper(final FileType fileType
, final Project project
) {
31 super(fileType
, project
);
34 protected int getIndentInner(final ASTNode element
, final boolean includeNonSpace
, final int recursionLevel
) {
35 if (recursionLevel
> TOO_BIG_WALK_THRESHOULD
) return 0;
37 if (element
.getTreePrev() != null) {
38 ASTNode prev
= element
.getTreePrev();
39 while (prev
instanceof CompositeElement
&& !TreeUtil
.isStrongWhitespaceHolder(prev
.getElementType())) {
40 ASTNode lastCompositePrev
= prev
;
41 prev
= prev
.getLastChildNode();
42 if (prev
== null) { // element.prev is "empty composite"
43 return getIndentInner(lastCompositePrev
, includeNonSpace
, recursionLevel
+ 1);
47 String text
= prev
.getText();
48 int index
= Math
.max(text
.lastIndexOf('\n'), text
.lastIndexOf('\r'));
51 return getIndent(text
.substring(index
+ 1), includeNonSpace
);
54 if (includeNonSpace
) {
55 return getIndentInner(prev
, includeNonSpace
, recursionLevel
+ 1) + getIndent(text
, includeNonSpace
);
58 if (element
.getElementType() == ElementType
.CODE_BLOCK
) {
59 ASTNode parent
= element
.getTreeParent();
60 if (parent
.getElementType() == ElementType
.BLOCK_STATEMENT
) {
61 parent
= parent
.getTreeParent();
63 if (parent
.getElementType() != ElementType
.CODE_BLOCK
) {
64 //Q: use some "anchor" part of parent for some elements?
65 // e.g. for method it could be declaration start, not doc-comment
66 return getIndentInner(parent
, includeNonSpace
, recursionLevel
+ 1);
70 if (element
.getElementType() == ElementType
.LBRACE
) {
71 return getIndentInner(element
.getTreeParent(), includeNonSpace
, recursionLevel
+ 1);
76 ASTNode parent
= prev
.getTreeParent();
78 while (parent
!= null) {
79 if (child
.getTreePrev() != null) break;
81 parent
= parent
.getTreeParent();
85 return getIndent(text
, includeNonSpace
);
88 if (prev
.getTreeParent().getElementType() == ElementType
.LABELED_STATEMENT
) {
89 return getIndentInner(prev
, true, recursionLevel
+ 1) + getIndent(text
, true);
92 return getIndentInner(prev
, includeNonSpace
, recursionLevel
+ 1);
96 if (element
.getTreeParent() == null) {
99 return getIndentInner(element
.getTreeParent(), includeNonSpace
, recursionLevel
+ 1);