Composite folding builder
[fedora-idea.git] / plugins / java-i18n / src / com / intellij / codeInspection / i18n / folding / PropertyFoldingBuilder.java
blobee4d9c850811d775eb7750e472dadef92af5860f
1 package com.intellij.codeInspection.i18n.folding;
3 import com.intellij.codeInsight.AnnotationUtil;
4 import com.intellij.codeInspection.i18n.JavaI18nUtil;
5 import com.intellij.lang.ASTNode;
6 import com.intellij.lang.folding.FoldingBuilder;
7 import com.intellij.lang.folding.FoldingDescriptor;
8 import com.intellij.lang.properties.psi.Property;
9 import com.intellij.lang.properties.references.I18nUtil;
10 import com.intellij.openapi.editor.Document;
11 import com.intellij.psi.*;
12 import com.intellij.psi.impl.ConstantExpressionEvaluator;
13 import com.intellij.psi.impl.source.SourceTreeToPsiMap;
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
20 /**
21 * @author Konstantin Bulenkov
23 public class PropertyFoldingBuilder implements FoldingBuilder {
24 public FoldingDescriptor[] buildFoldRegions(ASTNode node, Document document) {
25 final PsiElement element = node.getPsi();
26 if (!(element instanceof PsiJavaFile)) {
27 return FoldingDescriptor.EMPTY;
29 final PsiJavaFile file = (PsiJavaFile) element;
30 final List<FoldingDescriptor> result = new ArrayList<FoldingDescriptor>();
32 file.accept(new JavaRecursiveElementWalkingVisitor() {
33 @Override
34 public void visitLiteralExpression(PsiLiteralExpression expression) {
35 if (isI18nProperty(expression)) {
36 final String msg = getI18nMessage(expression);
38 final PsiElement parent = expression.getParent();
39 if (!msg.equals(expression.getText()) &&
40 parent instanceof PsiExpressionList &&
41 ((PsiExpressionList)parent).getExpressions()[0] == expression) {
42 final PsiExpressionList expressions = (PsiExpressionList)parent;
43 final int count = I18nUtil.getPropertyValueParamsMaxCount(expression);
44 final PsiExpression[] args = expressions.getExpressions();
45 if (args.length == 1 + count && parent.getParent() instanceof PsiMethodCallExpression) {
46 boolean ok = true;
47 for (int i = 1; i < count + 1; i++) {
48 Object value = ConstantExpressionEvaluator.computeConstantExpression(args[i], false);
49 if (value == null) {
50 if (!(args[i] instanceof PsiReferenceExpression)) {
51 ok = false;
52 break;
56 if (ok) {
57 result.add(new FoldingDescriptor(parent.getParent().getNode(), parent.getParent().getTextRange()));
58 return;
63 result.add(new FoldingDescriptor(expression.getNode(), expression.getTextRange()));
66 });
68 return result.toArray(new FoldingDescriptor[result.size()]);
73 public String getPlaceholderText(ASTNode node) {
74 final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(node);
75 if (element instanceof PsiLiteralExpression) {
76 return getI18nMessage((PsiLiteralExpression)element);
77 } else if (element instanceof PsiMethodCallExpression) {
78 return formatMethodCallExpression((PsiMethodCallExpression)element);
80 return element.getText();
83 private static String formatMethodCallExpression(PsiMethodCallExpression methodCallExpression) {
84 final PsiExpression[] args = methodCallExpression.getArgumentList().getExpressions();
85 if (args.length > 0
86 && args[0] instanceof PsiLiteralExpression
87 && isI18nProperty((PsiLiteralExpression)args[0])) {
88 final int count = I18nUtil.getPropertyValueParamsMaxCount((PsiLiteralExpression)args[0]);
89 if (args.length == 1 + count) {
90 String text = getI18nMessage((PsiLiteralExpression)args[0]);
91 for (int i = 1; i < count + 1; i++) {
92 Object value = ConstantExpressionEvaluator.computeConstantExpression(args[i], false);
93 if (value == null) {
94 if (args[i] instanceof PsiReferenceExpression) {
95 value = "{" + args[i].getText() + "}";
97 else {
98 text = null;
99 break;
102 text = text.replace("{" + (i - 1) + "}", value.toString());
104 if (text != null) {
105 if (!text.equals(methodCallExpression.getText())) {
106 text = text.replace("''", "'");
108 return text;
113 return methodCallExpression.getText();
116 private static String getI18nMessage(PsiLiteralExpression literal) {
117 if (isI18nProperty(literal)) {
118 final PsiReference[] references = literal.getReferences();
119 for (PsiReference reference : references) {
120 final PsiElement element = reference.resolve();
121 if (element instanceof Property) {
122 return "\"" + ((Property)element).getValue() + "\"";
126 return literal.getText();
129 public boolean isCollapsedByDefault(ASTNode node) {
130 return true;
134 private static boolean isI18nProperty(PsiLiteralExpression expr) {
135 final Map<String, Object> annotationParams = new HashMap<String, Object>();
136 annotationParams.put(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER, null);
137 return JavaI18nUtil.mustBePropertyKey(expr, annotationParams);