intelliLang injector redesign p1
[fedora-idea.git] / plugins / IntelliLang / src / org / intellij / plugins / intelliLang / util / SubstitutedExpressionEvaluationHelper.java
blob1b1db77df92caf2a5d7b7bf6b7de6f299e9a290a
1 /*
2 * Copyright 2006 Sascha Weinreuter
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.
16 package org.intellij.plugins.intelliLang.util;
18 import com.intellij.codeInsight.AnnotationUtil;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.psi.*;
21 import com.intellij.util.SmartList;
22 import org.intellij.plugins.intelliLang.Configuration;
23 import org.jetbrains.annotations.NotNull;
24 import org.jetbrains.annotations.Nullable;
26 import java.util.List;
28 /**
29 * Computes the constant value of an expression while considering the substitution annotation for non-compile-time
30 * constant expressions.
31 * <p/>
32 * This is a quite simplified implementation at the moment.
34 public class SubstitutedExpressionEvaluationHelper {
35 private final PsiConstantEvaluationHelper myHelper;
36 private final Configuration myConfiguration;
38 public SubstitutedExpressionEvaluationHelper(final Project project) {
39 myHelper = JavaPsiFacade.getInstance(project).getConstantEvaluationHelper();
40 myConfiguration = Configuration.getInstance();
43 @Nullable
44 public Object computeSimpleExpression(PsiExpression e) {
45 if (e instanceof PsiLiteralExpression) {
46 return myHelper.computeConstantExpression(e);
48 else if (e instanceof PsiReferenceExpression) {
49 final PsiReferenceExpression ref = (PsiReferenceExpression)e;
50 final PsiElement psiElement = ref.resolve();
51 if (psiElement != null) {
52 final Object o = myHelper.computeConstantExpression(e);
53 if (o != null) {
54 return o;
56 else if (psiElement instanceof PsiModifierListOwner) {
57 // find substitution
58 return calcSubstituted((PsiModifierListOwner)psiElement);
61 else {
62 // unresolvable... no luck
65 else if (e instanceof PsiParenthesizedExpression) {
66 return computeSimpleExpression(((PsiParenthesizedExpression)e).getExpression());
68 else if (e instanceof PsiMethodCallExpression) {
69 final PsiMethodCallExpression c = (PsiMethodCallExpression)e;
70 final PsiMethod m = (PsiMethod)c.getMethodExpression().resolve();
71 if (m != null && m.getReturnType() != PsiType.VOID) {
72 // find substitution
73 return calcSubstituted(m);
76 return myHelper.computeConstantExpression(e);
79 private Object calcSubstituted(final PsiModifierListOwner owner) {
80 final PsiAnnotation annotation = AnnotationUtil.findAnnotation(owner, myConfiguration.getSubstAnnotationPair().second);
81 if (annotation != null) {
82 return AnnotationUtilEx.calcAnnotationValue(annotation, "value");
84 return null;
87 /**
88 * Computes the value for the passed expression.
90 * @param e The expression whose value to compute
91 * @param nonConstant list that returns non-constant and non-substituted expressions
92 * @return the computed value, or null if the expression isn't compile time constant and not susbtituted
94 @Nullable
95 public static String computeExpression(@NotNull final PsiExpression e, @Nullable List<PsiExpression> nonConstant) {
96 final StringBuilder builder = new StringBuilder();
97 final List<PsiExpression> list = nonConstant != null ? nonConstant : new SmartList<PsiExpression>();
98 final PsiElementVisitor processor = new JavaRecursiveElementVisitor() {
99 SubstitutedExpressionEvaluationHelper helper = new SubstitutedExpressionEvaluationHelper(e.getProject());
100 @Override
101 public void visitConditionalExpression(PsiConditionalExpression expression) {
102 PsiExpression c = expression.getCondition();
103 final Object o = helper.myHelper.computeConstantExpression(c);
104 if (Boolean.TRUE.equals(o)) {
105 final PsiExpression then = expression.getThenExpression();
106 if (then != null) {
107 execute(then);
110 else if (Boolean.FALSE.equals(o)) {
111 final PsiExpression elseExpr = expression.getElseExpression();
112 if (elseExpr != null) {
113 execute(elseExpr);
116 else if (o == null) {
117 list.add(expression);
121 @Override
122 public void visitLiteralExpression(PsiLiteralExpression expression) {
123 execute(expression);
126 @Override
127 public void visitReferenceExpression(PsiReferenceExpression expression) {
128 execute(expression);
131 @Override
132 public void visitMethodCallExpression(PsiMethodCallExpression expression) {
133 execute(expression);
136 @Override
137 public void visitAssignmentExpression(PsiAssignmentExpression expression) {
138 final PsiExpression expr = expression.getRExpression();
139 if (expr != null) expr.accept(this);
142 public void execute(PsiExpression e) {
143 final Object s = helper.computeSimpleExpression(e);
144 if (s != null) {
145 builder.append(String.valueOf(s));
147 else {
148 list.add(e);
152 e.accept(processor);
154 return list.isEmpty() ? builder.toString() : null;