blob: cc8a8836180a053265e7998f252e6777a17f65e8 [file] [log] [blame]
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.uiDesigner.binding;
import com.intellij.lang.ASTNode;
import com.intellij.lang.folding.FoldingBuilderEx;
import com.intellij.lang.folding.FoldingDescriptor;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.uiDesigner.UIDesignerBundle;
import com.intellij.uiDesigner.compiler.AsmCodeGenerator;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author yole
*/
public class GeneratedCodeFoldingBuilder extends FoldingBuilderEx {
@NotNull
public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) {
MyFoldingVisitor visitor = new MyFoldingVisitor();
root.accept(visitor);
return visitor.myFoldingData.toArray(new FoldingDescriptor[visitor.myFoldingData.size()]);
}
public String getPlaceholderText(@NotNull ASTNode node) {
return UIDesignerBundle.message("uidesigner.generated.code.folding.placeholder.text");
}
public boolean isCollapsedByDefault(@NotNull ASTNode node) {
return true;
}
private static boolean isGeneratedUIInitializer(PsiClassInitializer initializer) {
PsiCodeBlock body = initializer.getBody();
if (body.getStatements().length != 1) return false;
PsiStatement statement = body.getStatements()[0];
if (!(statement instanceof PsiExpressionStatement) ||
!(((PsiExpressionStatement)statement).getExpression() instanceof PsiMethodCallExpression)) {
return false;
}
PsiMethodCallExpression call = (PsiMethodCallExpression)((PsiExpressionStatement)statement).getExpression();
return AsmCodeGenerator.SETUP_METHOD_NAME.equals(call.getMethodExpression().getReferenceName());
}
private static class MyFoldingVisitor extends JavaRecursiveElementWalkingVisitor {
private PsiElement myLastElement;
private final List<FoldingDescriptor> myFoldingData = new ArrayList<FoldingDescriptor>();
@Override
public void visitMethod(PsiMethod method) {
if (AsmCodeGenerator.SETUP_METHOD_NAME.equals(method.getName()) ||
AsmCodeGenerator.GET_ROOT_COMPONENT_METHOD_NAME.equals(method.getName()) ||
AsmCodeGenerator.LOAD_BUTTON_TEXT_METHOD.equals(method.getName()) ||
AsmCodeGenerator.LOAD_LABEL_TEXT_METHOD.equals(method.getName())) {
addFoldingData(method);
}
}
@Override
public void visitClassInitializer(PsiClassInitializer initializer) {
if (isGeneratedUIInitializer(initializer)) {
addFoldingData(initializer);
}
}
private void addFoldingData(final PsiElement element) {
PsiElement prevSibling = PsiTreeUtil.skipSiblingsBackward(element, PsiWhiteSpace.class);
synchronized (myFoldingData) {
if (myLastElement == null || prevSibling != myLastElement) {
myFoldingData.add(new FoldingDescriptor(element, element.getTextRange()));
}
else {
FoldingDescriptor lastDescriptor = myFoldingData.get(myFoldingData.size()-1);
final TextRange range = new TextRange(lastDescriptor.getRange().getStartOffset(), element.getTextRange().getEndOffset());
myFoldingData.set(myFoldingData.size()-1, new FoldingDescriptor(lastDescriptor.getElement(), range));
}
}
myLastElement = element;
}
}
}