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.
18 * Class EvaluatorBuilderImpl
21 package com.intellij.debugger.engine.evaluation.expression;
23 import com.intellij.codeInsight.daemon.JavaErrorMessages;
24 import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
25 import com.intellij.debugger.DebuggerBundle;
26 import com.intellij.debugger.SourcePosition;
27 import com.intellij.debugger.engine.ContextUtil;
28 import com.intellij.debugger.engine.DebuggerUtils;
29 import com.intellij.debugger.engine.JVMName;
30 import com.intellij.debugger.engine.JVMNameUtil;
31 import com.intellij.debugger.engine.evaluation.*;
32 import com.intellij.openapi.diagnostic.Logger;
33 import com.intellij.openapi.project.Project;
34 import com.intellij.psi.*;
35 import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
36 import com.intellij.psi.search.GlobalSearchScope;
37 import com.intellij.psi.tree.IElementType;
38 import com.intellij.psi.util.PsiTreeUtil;
39 import com.intellij.psi.util.PsiTypesUtil;
40 import com.intellij.psi.util.TypeConversionUtil;
41 import com.intellij.util.IncorrectOperationException;
42 import com.sun.jdi.Value;
43 import org.jetbrains.annotations.Nullable;
45 import java.util.ArrayList;
46 import java.util.HashSet;
47 import java.util.List;
50 public class EvaluatorBuilderImpl implements EvaluatorBuilder {
51 private static final EvaluatorBuilderImpl ourInstance = new EvaluatorBuilderImpl();
52 private final CodeFragmentFactory myCodeFactory;
54 private EvaluatorBuilderImpl() {
55 myCodeFactory = new CodeFragmentFactoryContextWrapper(DefaultCodeFragmentFactory.getInstance());
58 public static EvaluatorBuilder getInstance() {
62 public ExpressionEvaluator build(final TextWithImports text, final PsiElement contextElement, final SourcePosition position) throws EvaluateException {
63 if (contextElement == null) {
64 throw EvaluateExceptionUtil.CANNOT_FIND_SOURCE_CLASS;
67 final Project project = contextElement.getProject();
69 PsiCodeFragment codeFragment = myCodeFactory.createCodeFragment(text, contextElement, project);
70 if(codeFragment == null) {
71 throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", text.getText()));
73 codeFragment.forceResolveScope(GlobalSearchScope.allScope(project));
74 DebuggerUtils.checkSyntax(codeFragment);
76 return build(codeFragment, position);
79 public ExpressionEvaluator build(final PsiElement codeFragment, final SourcePosition position) throws EvaluateException {
80 return new Builder(position).buildElement(codeFragment);
83 private static class Builder extends JavaElementVisitor {
84 private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl");
85 private Evaluator myResult = null;
86 private PsiClass myContextPsiClass;
87 private CodeFragmentEvaluator myCurrentFragmentEvaluator;
88 private final Set<JavaCodeFragment> myVisitedFragments = new HashSet<JavaCodeFragment>();
90 private final SourcePosition myPosition;
92 private Builder(@Nullable SourcePosition position) {
93 myPosition = position;
97 public void visitCodeFragment(JavaCodeFragment codeFragment) {
98 myVisitedFragments.add(codeFragment);
99 ArrayList<Evaluator> evaluators = new ArrayList<Evaluator>();
101 CodeFragmentEvaluator oldFragmentEvaluator = myCurrentFragmentEvaluator;
102 myCurrentFragmentEvaluator = new CodeFragmentEvaluator(oldFragmentEvaluator);
104 for (PsiElement child = codeFragment.getFirstChild(); child != null; child = child.getNextSibling()) {
106 if(myResult != null) {
107 evaluators.add(myResult);
112 myCurrentFragmentEvaluator.setStatements(evaluators.toArray(new Evaluator[evaluators.size()]));
113 myResult = myCurrentFragmentEvaluator;
115 myCurrentFragmentEvaluator = oldFragmentEvaluator;
119 public void visitErrorElement(PsiErrorElement element) {
120 throw new EvaluateRuntimeException(EvaluateExceptionUtil
121 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", element.getText())));
125 public void visitAssignmentExpression(PsiAssignmentExpression expression) {
126 final PsiExpression rExpression = expression.getRExpression();
127 if(rExpression == null) {
128 throw new EvaluateRuntimeException(
129 EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText()))
133 rExpression.accept(this);
134 Evaluator rEvaluator = myResult;
136 if(expression.getOperationSign().getTokenType() != JavaTokenType.EQ) {
137 throw new EvaluateRuntimeException(
138 EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.operation.not.supported", expression.getOperationSign().getText()))
142 final PsiExpression lExpression = expression.getLExpression();
144 final PsiType lType = lExpression.getType();
146 throw new EvaluateRuntimeException(
147 EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", lExpression.getText()))
151 if(!TypeConversionUtil.areTypesAssignmentCompatible(lType, rExpression)) {
152 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.incompatible.types", expression.getOperationSign().getText())));
154 lExpression.accept(this);
155 Evaluator lEvaluator = myResult;
157 rEvaluator = handleAssignmentBoxingAndPrimitiveTypeConversions(lType, rExpression.getType(), rEvaluator);
159 myResult = new AssignmentEvaluator(lEvaluator, rEvaluator);
162 // returns rEvaluator possibly wrapped with boxing/unboxing and casting evaluators
163 private static Evaluator handleAssignmentBoxingAndPrimitiveTypeConversions(PsiType lType, PsiType rType, Evaluator rEvaluator) {
164 final PsiType unboxedLType = PsiPrimitiveType.getUnboxedType(lType);
166 if (unboxedLType != null) {
167 if (rType instanceof PsiPrimitiveType && !PsiPrimitiveType.NULL.equals(rType)) {
168 if (!rType.equals(unboxedLType)) {
169 rEvaluator = new TypeCastEvaluator(rEvaluator, unboxedLType.getCanonicalText(), true);
171 rEvaluator = new BoxingEvaluator(rEvaluator);
175 // either primitive type or not unboxable type
176 if (lType instanceof PsiPrimitiveType) {
177 if (rType instanceof PsiClassType) {
178 rEvaluator = new UnBoxingEvaluator(rEvaluator);
180 final PsiPrimitiveType unboxedRType = PsiPrimitiveType.getUnboxedType(rType);
181 final PsiType _rType = unboxedRType != null? unboxedRType : rType;
182 if (_rType instanceof PsiPrimitiveType && !PsiPrimitiveType.NULL.equals(_rType)) {
183 if (!lType.equals(_rType)) {
184 rEvaluator = new TypeCastEvaluator(rEvaluator, lType.getCanonicalText(), true);
193 public void visitStatement(PsiStatement statement) {
194 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.statement.not.supported", statement.getText())));
198 public void visitBlockStatement(PsiBlockStatement statement) {
199 PsiStatement[] statements = statement.getCodeBlock().getStatements();
200 Evaluator [] evaluators = new Evaluator[statements.length];
201 for (int i = 0; i < statements.length; i++) {
202 PsiStatement psiStatement = statements[i];
203 psiStatement.accept(this);
204 evaluators[i] = myResult;
207 myResult = new BlockStatementEvaluator(evaluators);
211 public void visitWhileStatement(PsiWhileStatement statement) {
212 PsiStatement body = statement.getBody();
213 if(body == null) return;
215 Evaluator bodyEvaluator = myResult;
217 PsiExpression condition = statement.getCondition();
218 if(condition == null) return;
219 condition.accept(this);
221 if(statement.getParent() instanceof PsiLabeledStatement) {
222 label = ((PsiLabeledStatement)statement.getParent()).getLabelIdentifier().getText();
224 myResult = new WhileStatementEvaluator(myResult, bodyEvaluator, label);
228 public void visitForStatement(PsiForStatement statement) {
229 PsiStatement initializer = statement.getInitialization();
230 Evaluator initializerEvaluator = null;
231 if(initializer != null){
232 initializer.accept(this);
233 initializerEvaluator = myResult;
236 PsiExpression condition = statement.getCondition();
237 Evaluator conditionEvaluator = null;
238 if(condition != null) {
239 condition.accept(this);
240 conditionEvaluator = myResult;
243 PsiStatement update = statement.getUpdate();
244 Evaluator updateEvaluator = null;
247 updateEvaluator = myResult;
250 PsiStatement body = statement.getBody();
251 if(body == null) return;
253 Evaluator bodyEvaluator = myResult;
256 if(statement.getParent() instanceof PsiLabeledStatement) {
257 label = ((PsiLabeledStatement)statement.getParent()).getLabelIdentifier().getText();
259 myResult = new ForStatementEvaluator(initializerEvaluator, conditionEvaluator, updateEvaluator, bodyEvaluator, label);
263 public void visitIfStatement(PsiIfStatement statement) {
264 PsiStatement thenBranch = statement.getThenBranch();
265 if(thenBranch == null) return;
266 thenBranch.accept(this);
267 Evaluator thenEvaluator = myResult;
269 PsiStatement elseBranch = statement.getElseBranch();
270 Evaluator elseEvaluator = null;
271 if(elseBranch != null){
272 elseBranch.accept(this);
273 elseEvaluator = myResult;
276 PsiExpression condition = statement.getCondition();
277 if(condition == null) return;
278 condition.accept(this);
280 myResult = new IfStatementEvaluator(myResult, thenEvaluator, elseEvaluator);
284 public void visitBreakStatement(PsiBreakStatement statement) {
285 PsiIdentifier labelIdentifier = statement.getLabelIdentifier();
286 myResult = BreakContinueStatementEvaluator.createBreakEvaluator(labelIdentifier != null ? labelIdentifier.getText() : null);
290 public void visitContinueStatement(PsiContinueStatement statement) {
291 PsiIdentifier labelIdentifier = statement.getLabelIdentifier();
292 myResult = BreakContinueStatementEvaluator.createContinueEvaluator(labelIdentifier != null ? labelIdentifier.getText() : null);
296 public void visitExpressionStatement(PsiExpressionStatement statement) {
297 statement.getExpression().accept(this);
301 public void visitExpression(PsiExpression expression) {
302 if (LOG.isDebugEnabled()) {
303 LOG.debug("visitExpression " + expression);
308 public void visitBinaryExpression(PsiBinaryExpression expression) {
309 if (LOG.isDebugEnabled()) {
310 LOG.debug("visitBinaryExpression " + expression);
312 final PsiExpression lOperand = expression.getLOperand();
313 lOperand.accept(this);
314 Evaluator lResult = myResult;
315 final PsiExpression rOperand = expression.getROperand();
316 if(rOperand == null) {
317 throw new EvaluateRuntimeException(
318 EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText()))
321 rOperand.accept(this);
322 Evaluator rResult = myResult;
323 IElementType opType = expression.getOperationSign().getTokenType();
324 PsiType expressionExpectedType = expression.getType();
325 if (expressionExpectedType == null) {
326 throw new EvaluateRuntimeException(
327 EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText()))
330 myResult = createBinaryEvaluator(lResult, lOperand.getType(), rResult, rOperand.getType(), opType, expressionExpectedType);
334 // constructs binary evaluator handling unboxing and numeric promotion issues
335 private static BinaryExpressionEvaluator createBinaryEvaluator(
336 Evaluator lResult, final PsiType lType, Evaluator rResult, final PsiType rType, final IElementType operation, final PsiType expressionExpectedType) {
337 // handle unboxing if neccesary
338 if (isUnboxingInBinaryExpressionApplicable(lType, rType, operation)) {
339 if (rType instanceof PsiClassType && UnBoxingEvaluator.isTypeUnboxable(rType.getCanonicalText())) {
340 rResult = new UnBoxingEvaluator(rResult);
342 if (lType instanceof PsiClassType && UnBoxingEvaluator.isTypeUnboxable(lType.getCanonicalText())) {
343 lResult = new UnBoxingEvaluator(lResult);
346 if (isBinaryNumericPromotionApplicable(lType, rType, operation)) {
347 PsiType _lType = lType;
348 final PsiPrimitiveType unboxedLType = PsiPrimitiveType.getUnboxedType(lType);
349 if (unboxedLType != null) {
350 _lType = unboxedLType;
353 PsiType _rType = rType;
354 final PsiPrimitiveType unboxedRType = PsiPrimitiveType.getUnboxedType(rType);
355 if (unboxedRType != null) {
356 _rType = unboxedRType;
359 // handle numeric promotion
360 if (PsiType.DOUBLE.equals(_lType)) {
361 if (TypeConversionUtil.areTypesConvertible(_rType, PsiType.DOUBLE)) {
362 rResult = new TypeCastEvaluator(rResult, PsiType.DOUBLE.getCanonicalText(), true);
365 else if (PsiType.DOUBLE.equals(_rType)) {
366 if (TypeConversionUtil.areTypesConvertible(_lType, PsiType.DOUBLE)) {
367 lResult = new TypeCastEvaluator(lResult, PsiType.DOUBLE.getCanonicalText(), true);
370 else if (PsiType.FLOAT.equals(_lType)) {
371 if (TypeConversionUtil.areTypesConvertible(_rType, PsiType.FLOAT)) {
372 rResult = new TypeCastEvaluator(rResult, PsiType.FLOAT.getCanonicalText(), true);
375 else if (PsiType.FLOAT.equals(_rType)) {
376 if (TypeConversionUtil.areTypesConvertible(_lType, PsiType.FLOAT)) {
377 lResult = new TypeCastEvaluator(lResult, PsiType.FLOAT.getCanonicalText(), true);
380 else if (PsiType.LONG.equals(_lType)) {
381 if (TypeConversionUtil.areTypesConvertible(_rType, PsiType.LONG)) {
382 rResult = new TypeCastEvaluator(rResult, PsiType.LONG.getCanonicalText(), true);
385 else if (PsiType.LONG.equals(_rType)) {
386 if (TypeConversionUtil.areTypesConvertible(_lType, PsiType.LONG)) {
387 lResult = new TypeCastEvaluator(lResult, PsiType.LONG.getCanonicalText(), true);
391 if (!PsiType.INT.equals(_lType) && TypeConversionUtil.areTypesConvertible(_lType, PsiType.INT)) {
392 lResult = new TypeCastEvaluator(lResult, PsiType.INT.getCanonicalText(), true);
394 if (!PsiType.INT.equals(_rType) && TypeConversionUtil.areTypesConvertible(_rType, PsiType.INT)) {
395 rResult = new TypeCastEvaluator(rResult, PsiType.INT.getCanonicalText(), true);
400 return new BinaryExpressionEvaluator(lResult, rResult, operation, expressionExpectedType.getCanonicalText());
403 private static boolean isBinaryNumericPromotionApplicable(PsiType lType, PsiType rType, IElementType opType) {
404 if (lType == null || rType == null) {
407 if (opType == JavaTokenType.EQEQ || opType == JavaTokenType.NE) {
408 if (PsiType.NULL.equals(lType) || PsiType.NULL.equals(rType)) {
411 if (lType instanceof PsiClassType && rType instanceof PsiClassType) {
414 if (lType instanceof PsiClassType) {
415 return PsiPrimitiveType.getUnboxedType(lType) != null; // should be unboxable
417 if (rType instanceof PsiClassType) {
418 return PsiPrimitiveType.getUnboxedType(rType) != null; // should be unboxable
423 return opType == JavaTokenType.ASTERISK ||
424 opType == JavaTokenType.DIV ||
425 opType == JavaTokenType.PERC ||
426 opType == JavaTokenType.PLUS ||
427 opType == JavaTokenType.MINUS ||
428 opType == JavaTokenType.LT ||
429 opType == JavaTokenType.LE ||
430 opType == JavaTokenType.GT ||
431 opType == JavaTokenType.GE ||
432 opType == JavaTokenType.AND ||
433 opType == JavaTokenType.XOR ||
434 opType == JavaTokenType.OR;
438 private static boolean isUnboxingInBinaryExpressionApplicable(PsiType lType, PsiType rType, IElementType opCode) {
439 if (PsiType.NULL.equals(lType) || PsiType.NULL.equals(rType)) {
442 // handle '==' and '!=' separately
443 if (opCode == JavaTokenType.EQEQ || opCode == JavaTokenType.NE) {
444 return (lType instanceof PsiPrimitiveType && rType instanceof PsiClassType) ||
445 (lType instanceof PsiClassType && rType instanceof PsiPrimitiveType);
447 // all other operations at least one should be of class type
448 return lType instanceof PsiClassType || rType instanceof PsiClassType;
453 * @return promotion type to cast to or null if no casting needed
456 private static PsiType calcUnaryNumericPromotionType(PsiPrimitiveType type) {
457 if (PsiType.BYTE.equals(type) || PsiType.SHORT.equals(type) || PsiType.CHAR.equals(type) || PsiType.INT.equals(type)) {
464 public void visitDeclarationStatement(PsiDeclarationStatement statement) {
465 List<Evaluator> evaluators = new ArrayList<Evaluator>();
467 PsiElement[] declaredElements = statement.getDeclaredElements();
468 for (PsiElement declaredElement : declaredElements) {
469 if (declaredElement instanceof PsiLocalVariable) {
470 if (myCurrentFragmentEvaluator != null) {
471 final PsiLocalVariable localVariable = ((PsiLocalVariable)declaredElement);
473 final PsiType lType = localVariable.getType();
475 PsiElementFactory elementFactory = JavaPsiFacade.getInstance(localVariable.getProject()).getElementFactory();
477 PsiExpression initialValue = elementFactory.createExpressionFromText(PsiTypesUtil.getDefaultValueOfType(lType), null);
478 Object value = JavaConstantExpressionEvaluator.computeConstantExpression(initialValue, true);
479 myCurrentFragmentEvaluator.setInitialValue(localVariable.getName(), value);
481 catch (IncorrectOperationException e) {
484 catch (EvaluateException e) {
485 throw new EvaluateRuntimeException(e);
488 PsiExpression initializer = localVariable.getInitializer();
489 if (initializer != null) {
491 if (!TypeConversionUtil.areTypesAssignmentCompatible(localVariable.getType(), initializer)) {
492 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
493 DebuggerBundle.message("evaluation.error.incompatible.variable.initializer.type", localVariable.getName())));
495 final PsiType rType = initializer.getType();
496 initializer.accept(this);
497 Evaluator rEvaluator = myResult;
499 PsiExpression localVarReference = elementFactory.createExpressionFromText(localVariable.getName(), initializer);
501 localVarReference.accept(this);
502 Evaluator lEvaluator = myResult;
503 rEvaluator = handleAssignmentBoxingAndPrimitiveTypeConversions(localVarReference.getType(), rType, rEvaluator);
505 Evaluator assignment = new AssignmentEvaluator(lEvaluator, rEvaluator);
506 evaluators.add(assignment);
508 catch (IncorrectOperationException e) {
514 throw new EvaluateRuntimeException(new EvaluateException(
515 DebuggerBundle.message("evaluation.error.local.variable.declarations.not.supported"), null));
519 throw new EvaluateRuntimeException(new EvaluateException(
520 DebuggerBundle.message("evaluation.error.unsupported.declaration", declaredElement.getText()), null));
524 if(evaluators.size() > 0) {
525 CodeFragmentEvaluator codeFragmentEvaluator = new CodeFragmentEvaluator(myCurrentFragmentEvaluator);
526 codeFragmentEvaluator.setStatements(evaluators.toArray(new Evaluator[0]));
527 myResult = codeFragmentEvaluator;
534 public void visitConditionalExpression(PsiConditionalExpression expression) {
535 if (LOG.isDebugEnabled()) {
536 LOG.debug("visitConditionalExpression " + expression);
538 final PsiExpression thenExpression = expression.getThenExpression();
539 final PsiExpression elseExpression = expression.getElseExpression();
540 if (thenExpression == null || elseExpression == null){
541 throw new EvaluateRuntimeException(EvaluateExceptionUtil
542 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
544 PsiExpression condition = expression.getCondition();
545 condition.accept(this);
546 if (myResult == null) {
547 throw new EvaluateRuntimeException(EvaluateExceptionUtil
548 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", condition.getText())));
550 Evaluator conditionEvaluator = myResult;
551 thenExpression.accept(this);
552 if (myResult == null) {
553 throw new EvaluateRuntimeException(EvaluateExceptionUtil
554 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", thenExpression.getText())));
556 Evaluator thenEvaluator = myResult;
557 elseExpression.accept(this);
558 if (myResult == null) {
559 throw new EvaluateRuntimeException(EvaluateExceptionUtil
560 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", elseExpression.getText())));
562 Evaluator elseEvaluator = myResult;
563 myResult = new ConditionalExpressionEvaluator(conditionEvaluator, thenEvaluator, elseEvaluator);
567 public void visitReferenceExpression(PsiReferenceExpression expression) {
568 if (LOG.isDebugEnabled()) {
569 LOG.debug("visitReferenceExpression " + expression);
571 PsiExpression qualifier = expression.getQualifierExpression();
572 PsiElement element = expression.resolve();
574 if (element instanceof PsiLocalVariable || element instanceof PsiParameter) {
575 final Value labeledValue = element.getUserData(CodeFragmentFactoryContextWrapper.LABEL_VARIABLE_VALUE_KEY);
576 if (labeledValue != null) {
577 myResult = new IdentityEvaluator(labeledValue);
581 final PsiFile containingFile = element.getContainingFile();
582 if(containingFile instanceof PsiCodeFragment && myCurrentFragmentEvaluator != null && myVisitedFragments.contains(((PsiCodeFragment)containingFile))) {
583 // psiVariable may live in PsiCodeFragment not only in debugger editors, for example Fabrique has such variables.
584 // So treat it as synthetic var only when this code fragment is located in DebuggerEditor,
585 // that's why we need to check that containing code fragment is the one we visited
586 myResult = new SyntheticVariableEvaluator(myCurrentFragmentEvaluator, ((PsiVariable)element).getName());
590 final PsiVariable psiVar = (PsiVariable)element;
591 final String localName = psiVar.getName();
592 PsiClass variableClass = getContainingClass(psiVar);
593 if (getContextPsiClass() == null || getContextPsiClass().equals(variableClass)) {
594 final LocalVariableEvaluator localVarEvaluator = new LocalVariableEvaluator(localName, ContextUtil.isJspImplicit(element));
595 if (psiVar instanceof PsiParameter) {
596 final PsiParameter param = (PsiParameter)psiVar;
597 final PsiParameterList paramList = PsiTreeUtil.getParentOfType(param, PsiParameterList.class, true);
598 if (paramList != null) {
599 localVarEvaluator.setParameterIndex(paramList.getParameterIndex(param));
602 myResult = localVarEvaluator;
605 // the expression references final var outside the context's class (in some of the outer classes)
606 int iterationCount = 0;
607 PsiClass aClass = getOuterClass(getContextPsiClass());
608 while (aClass != null && !aClass.equals(variableClass)) {
610 aClass = getOuterClass(aClass);
612 if (aClass != null) {
613 if(psiVar.getInitializer() != null) {
614 Object value = JavaPsiFacade.getInstance(psiVar.getProject()).getConstantEvaluationHelper().computeConstantExpression(psiVar.getInitializer());
616 myResult = new LiteralEvaluator(value, psiVar.getType().getCanonicalText());
620 Evaluator objectEvaluator = new ThisEvaluator(iterationCount);
621 //noinspection HardCodedStringLiteral
622 final PsiClass classAt = myPosition != null? JVMNameUtil.getClassAt(myPosition) : null;
623 FieldEvaluator.TargetClassFilter filter = FieldEvaluator.createClassFilter(classAt != null? classAt : getContextPsiClass());
624 myResult = new FieldEvaluator(objectEvaluator, filter, "val$" + localName);
627 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
628 DebuggerBundle.message("evaluation.error.local.variable.missing.from.class.closure", localName))
631 else if (element instanceof PsiField) {
632 final PsiField psiField = (PsiField)element;
633 final PsiClass fieldClass = psiField.getContainingClass();
634 if(fieldClass == null) {
635 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
636 DebuggerBundle.message("evaluation.error.cannot.resolve.field.class", psiField.getName())));
638 Evaluator objectEvaluator;
639 if (psiField.hasModifierProperty(PsiModifier.STATIC)) {
640 objectEvaluator = new TypeEvaluator(JVMNameUtil.getContextClassJVMQualifiedName(SourcePosition.createFromElement(psiField)));
642 else if(qualifier != null) {
643 qualifier.accept(this);
644 objectEvaluator = myResult;
646 else if (fieldClass.equals(getContextPsiClass()) || getContextPsiClass().isInheritor(fieldClass, true)) {
647 objectEvaluator = new ThisEvaluator();
649 else { // myContextPsiClass != fieldClass && myContextPsiClass is not a subclass of fieldClass
650 int iterationCount = 0;
651 PsiClass aClass = getContextPsiClass();
652 while (aClass != null && !(aClass.equals(fieldClass) || aClass.isInheritor(fieldClass, true))) {
654 aClass = getOuterClass(aClass);
656 if (aClass == null) {
657 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
658 DebuggerBundle.message("evaluation.error.cannot.sources.for.field.class", psiField.getName())));
660 objectEvaluator = new ThisEvaluator(iterationCount);
662 myResult = new FieldEvaluator(objectEvaluator, FieldEvaluator.createClassFilter(fieldClass), psiField.getName());
665 //let's guess what this could be
666 PsiElement nameElement = expression.getReferenceNameElement(); // get "b" part
668 if (nameElement instanceof PsiIdentifier) {
669 name = nameElement.getText();
672 //noinspection HardCodedStringLiteral
673 final String elementDisplayString = (nameElement != null ? nameElement.getText() : "(null)");
674 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
675 DebuggerBundle.message("evaluation.error.identifier.expected", elementDisplayString)));
678 if(qualifier != null) {
679 final PsiElement qualifierTarget = (qualifier instanceof PsiReferenceExpression) ? ((PsiReferenceExpression)qualifier).resolve() : null;
680 if (qualifierTarget instanceof PsiClass) {
681 // this is a call to a 'static' field
682 PsiClass psiClass = (PsiClass)qualifierTarget;
683 final JVMName typeName = JVMNameUtil.getJVMQualifiedName(psiClass);
684 myResult = new FieldEvaluator(new TypeEvaluator(typeName), FieldEvaluator.createClassFilter(psiClass), name);
687 PsiType type = qualifier.getType();
689 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
690 DebuggerBundle.message("evaluation.error.qualifier.type.unknown", qualifier.getText()))
694 qualifier.accept(this);
695 if (myResult == null) {
696 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
697 DebuggerBundle.message("evaluation.error.cannot.evaluate.qualifier", qualifier.getText()))
701 myResult = new FieldEvaluator(myResult, FieldEvaluator.createClassFilter(type), name);
705 myResult = new LocalVariableEvaluator(name, false);
711 public void visitSuperExpression(PsiSuperExpression expression) {
712 if (LOG.isDebugEnabled()) {
713 LOG.debug("visitSuperExpression " + expression);
715 final int iterationCount = calcIterationCount(expression.getQualifier());
716 myResult = new SuperEvaluator(iterationCount);
720 public void visitThisExpression(PsiThisExpression expression) {
721 if (LOG.isDebugEnabled()) {
722 LOG.debug("visitThisExpression " + expression);
724 final int iterationCount = calcIterationCount(expression.getQualifier());
725 myResult = new ThisEvaluator(iterationCount);
728 private int calcIterationCount(final PsiJavaCodeReferenceElement qualifier) {
729 int iterationCount = 0;
730 if (qualifier != null) {
731 PsiElement targetClass = qualifier.resolve();
732 if (targetClass == null || getContextPsiClass() == null) {
733 throw new EvaluateRuntimeException(EvaluateExceptionUtil
734 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", qualifier.getText())));
737 PsiClass aClass = getContextPsiClass();
738 while (aClass != null && !aClass.equals(targetClass)) {
740 aClass = getOuterClass(aClass);
743 catch (Exception e) {
744 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(e));
747 return iterationCount;
751 public void visitInstanceOfExpression(PsiInstanceOfExpression expression) {
752 if (LOG.isDebugEnabled()) {
753 LOG.debug("visitInstanceOfExpression " + expression);
755 PsiTypeElement checkType = expression.getCheckType();
756 if(checkType == null) {
757 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
759 PsiType type = checkType.getType();
760 expression.getOperand().accept(this);
761 // ClassObjectEvaluator typeEvaluator = new ClassObjectEvaluator(type.getCanonicalText());
762 Evaluator operandEvaluator = myResult;
763 myResult = new InstanceofEvaluator(operandEvaluator, new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(type)));
767 public void visitParenthesizedExpression(PsiParenthesizedExpression expression) {
768 if (LOG.isDebugEnabled()) {
769 LOG.debug("visitParenthesizedExpression " + expression);
771 PsiExpression expr = expression.getExpression();
778 public void visitPostfixExpression(PsiPostfixExpression expression) {
779 if(expression.getType() == null) {
780 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
781 DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText()))
785 final PsiExpression operandExpression = expression.getOperand();
786 operandExpression.accept(this);
788 final Evaluator operandEvaluator = myResult;
790 final IElementType operation = expression.getOperationSign().getTokenType();
791 final PsiType operandType = operandExpression.getType();
792 final @Nullable PsiType unboxedOperandType = PsiPrimitiveType.getUnboxedType(operandType);
794 Evaluator incrementImpl = createBinaryEvaluator(
795 operandEvaluator, operandType,
796 new LiteralEvaluator(Integer.valueOf(1), "int"), PsiType.INT,
797 operation == JavaTokenType.PLUSPLUS ? JavaTokenType.PLUS : JavaTokenType.MINUS,
798 unboxedOperandType!= null? unboxedOperandType : operandType
800 if (unboxedOperandType != null) {
801 incrementImpl = new BoxingEvaluator(incrementImpl);
803 myResult = new PostfixOperationEvaluator(operandEvaluator, incrementImpl);
807 public void visitPrefixExpression(final PsiPrefixExpression expression) {
808 final PsiType expressionType = expression.getType();
809 if(expressionType == null) {
810 throw new EvaluateRuntimeException(
811 EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText()))
815 final PsiExpression operandExpression = expression.getOperand();
816 if (operandExpression == null) {
817 throw new EvaluateRuntimeException(
818 EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.operand", expression.getText()))
822 operandExpression.accept(this);
823 Evaluator operandEvaluator = myResult;
825 // handle unboxing issues
826 final PsiType operandType = operandExpression.getType();
828 final PsiType unboxedOperandType = PsiPrimitiveType.getUnboxedType(operandType);
830 final IElementType operation = expression.getOperationSign().getTokenType();
832 if(operation == JavaTokenType.PLUSPLUS || operation == JavaTokenType.MINUSMINUS) {
834 final BinaryExpressionEvaluator rightEval = createBinaryEvaluator(
835 operandEvaluator, operandType,
836 new LiteralEvaluator(Integer.valueOf(1), "int"), PsiType.INT,
837 operation == JavaTokenType.PLUSPLUS ? JavaTokenType.PLUS : JavaTokenType.MINUS,
838 unboxedOperandType!= null? unboxedOperandType : operandType
840 myResult = new AssignmentEvaluator(operandEvaluator, unboxedOperandType != null? new BoxingEvaluator(rightEval) : rightEval);
842 catch (IncorrectOperationException e) {
847 if (JavaTokenType.PLUS.equals(operation) || JavaTokenType.MINUS.equals(operation)|| JavaTokenType.TILDE.equals(operation)) {
848 operandEvaluator = handleUnaryNumericPromotion(operandType, operandEvaluator);
851 if (unboxedOperandType != null) {
852 operandEvaluator = new UnBoxingEvaluator(operandEvaluator);
855 myResult = new UnaryExpressionEvaluator(operation, expressionType.getCanonicalText(), operandEvaluator, expression.getOperationSign().getText());
860 public void visitMethodCallExpression(PsiMethodCallExpression expression) {
861 if (LOG.isDebugEnabled()) {
862 LOG.debug("visitMethodCallExpression " + expression);
864 final PsiExpressionList argumentList = expression.getArgumentList();
865 final PsiExpression[] argExpressions = argumentList.getExpressions();
866 List<Evaluator> argumentEvaluators = new ArrayList<Evaluator>(argExpressions.length);
867 // evaluate arguments
868 for (PsiExpression psiExpression : argExpressions) {
869 psiExpression.accept(this);
870 if (myResult == null) {
871 // cannot build evaluator
872 throw new EvaluateRuntimeException(
873 EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", psiExpression.getText()))
876 argumentEvaluators.add(myResult);
878 PsiReferenceExpression methodExpr = expression.getMethodExpression();
880 final JavaResolveResult resolveResult = methodExpr.advancedResolve(false);
881 final PsiMethod psiMethod = (PsiMethod)resolveResult.getElement();
883 PsiExpression qualifier = methodExpr.getQualifierExpression();
884 Evaluator objectEvaluator;
885 JVMName contextClass = null;
887 if(psiMethod != null) {
888 PsiClass methodPsiClass = psiMethod.getContainingClass();
889 contextClass = JVMNameUtil.getJVMQualifiedName(methodPsiClass);
890 if (psiMethod.hasModifierProperty(PsiModifier.STATIC)) {
891 objectEvaluator = new TypeEvaluator(contextClass);
893 else if (qualifier != null ) {
894 qualifier.accept(this);
895 objectEvaluator = myResult;
898 int iterationCount = 0;
899 final PsiElement currentFileResolveScope = resolveResult.getCurrentFileResolveScope();
900 if (currentFileResolveScope instanceof PsiClass) {
901 PsiClass aClass = getContextPsiClass();
902 while(aClass != null && !aClass.equals(currentFileResolveScope)) {
903 aClass = getOuterClass(aClass);
907 objectEvaluator = new ThisEvaluator(iterationCount);
912 if (qualifier != null) {
913 PsiType type = qualifier.getType();
916 contextClass = JVMNameUtil.getJVMQualifiedName(type);
919 if (qualifier instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifier).resolve() instanceof PsiClass) {
920 // this is a call to a 'static' method
921 if (contextClass == null && type == null) {
922 throw new EvaluateRuntimeException(
923 EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.qualifier.type.unknown", qualifier.getText()))
926 assert contextClass != null;
927 objectEvaluator = new TypeEvaluator(contextClass);
930 qualifier.accept(this);
931 objectEvaluator = myResult;
935 objectEvaluator = new ThisEvaluator();
936 contextClass = JVMNameUtil.getContextClassJVMQualifiedName(myPosition);
937 if(contextClass == null && myContextPsiClass != null) {
938 contextClass = JVMNameUtil.getJVMQualifiedName(myContextPsiClass);
941 // throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
942 // DebuggerBundle.message("evaluation.error.method.not.found", methodExpr.getReferenceName()))
948 if (objectEvaluator == null) {
949 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
952 if (psiMethod != null && !psiMethod.isConstructor()) {
953 if (psiMethod.getReturnType() == null) {
954 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.unknown.method.return.type", psiMethod.getText())));
958 if (psiMethod != null) {
960 final PsiParameter[] declaredParams = psiMethod.getParameterList().getParameters();
961 for (int i = 0, parametersLength = declaredParams.length; i < parametersLength; i++) {
962 if (i >= argExpressions.length) {
963 break; // actual arguments count is less than number of declared params
965 final PsiType declaredParamType = declaredParams[i].getType();
966 final PsiType actualArgType = argExpressions[i].getType();
967 if (TypeConversionUtil.boxingConversionApplicable(declaredParamType, actualArgType)) {
968 final Evaluator argEval = argumentEvaluators.get(i);
969 argumentEvaluators.set(i, (declaredParamType instanceof PsiPrimitiveType)? new UnBoxingEvaluator(argEval) : new BoxingEvaluator(argEval));
974 myResult = new MethodEvaluator(objectEvaluator, contextClass, methodExpr.getReferenceName(), psiMethod != null ? JVMNameUtil.getJVMSignature(psiMethod) : null, argumentEvaluators);
978 public void visitLiteralExpression(PsiLiteralExpression expression) {
979 Object value = expression.getValue();
980 if(expression.getParsingError() != null) {
981 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(expression.getParsingError()));
983 myResult = new LiteralEvaluator(value, expression.getType().getCanonicalText());
987 public void visitArrayAccessExpression(PsiArrayAccessExpression expression) {
988 final PsiExpression indexExpression = expression.getIndexExpression();
989 if(indexExpression == null) {
990 throw new EvaluateRuntimeException(EvaluateExceptionUtil
991 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
993 indexExpression.accept(this);
994 final Evaluator indexEvaluator = handleUnaryNumericPromotion(indexExpression.getType(), myResult);
996 expression.getArrayExpression().accept(this);
997 Evaluator arrayEvaluator = myResult;
998 myResult = new ArrayAccessEvaluator(arrayEvaluator, indexEvaluator);
1003 * Handles unboxing and numeric promotion issues for
1004 * - array diumention expressions
1005 * - array index expression
1006 * - unary +, -, and ~ operations
1007 * @param operandExpressionType
1008 * @param operandEvaluator @return operandEvaluator possibly 'wrapped' with neccesary unboxing and type-casting evaluators to make returning value
1009 * sutable for mentioned contexts
1011 private static Evaluator handleUnaryNumericPromotion(final PsiType operandExpressionType, Evaluator operandEvaluator) {
1012 final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(operandExpressionType);
1013 if (unboxedType != null && !PsiType.BOOLEAN.equals(unboxedType)) {
1014 operandEvaluator = new UnBoxingEvaluator(operandEvaluator);
1017 // handle numeric promotion
1018 final PsiType _unboxedIndexType = unboxedType != null? unboxedType : operandExpressionType;
1019 if (_unboxedIndexType instanceof PsiPrimitiveType) {
1020 final PsiType promotionType = calcUnaryNumericPromotionType((PsiPrimitiveType)_unboxedIndexType);
1021 if (promotionType != null) {
1022 operandEvaluator = new TypeCastEvaluator(operandEvaluator, promotionType.getCanonicalText(), true);
1025 return operandEvaluator;
1028 @SuppressWarnings({"ConstantConditions"})
1030 public void visitTypeCastExpression(PsiTypeCastExpression expression) {
1031 final PsiExpression operandExpr = expression.getOperand();
1032 operandExpr.accept(this);
1033 Evaluator operandEvaluator = myResult;
1034 final PsiType castType = expression.getCastType().getType();
1035 final PsiType operandType = operandExpr.getType();
1037 if (castType != null && operandType != null && !TypeConversionUtil.areTypesConvertible(operandType, castType)) {
1038 throw new EvaluateRuntimeException(
1039 new EvaluateException(JavaErrorMessages.message("inconvertible.type.cast", HighlightUtil.formatType(operandType), HighlightUtil.formatType(castType)))
1043 final boolean shouldPerformBoxingConversion = castType != null && operandType != null && TypeConversionUtil.boxingConversionApplicable(castType, operandType);
1044 final boolean castingToPrimitive = castType instanceof PsiPrimitiveType;
1045 if (shouldPerformBoxingConversion && castingToPrimitive) {
1046 operandEvaluator = new UnBoxingEvaluator(operandEvaluator);
1049 final boolean performCastToWrapperClass = shouldPerformBoxingConversion && !castingToPrimitive;
1051 String castTypeName = castType.getCanonicalText();
1052 if (performCastToWrapperClass) {
1053 final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(castType);
1054 if (unboxedType != null) {
1055 castTypeName = unboxedType.getCanonicalText();
1059 myResult = new TypeCastEvaluator(operandEvaluator, castTypeName, castingToPrimitive);
1061 if (performCastToWrapperClass) {
1062 myResult = new BoxingEvaluator(myResult);
1067 public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
1068 PsiType type = expression.getOperand().getType();
1070 if (type instanceof PsiPrimitiveType) {
1071 final JVMName typeName = JVMNameUtil.getJVMRawText(((PsiPrimitiveType)type).getBoxedTypeName());
1072 myResult = new FieldEvaluator(new TypeEvaluator(typeName), FieldEvaluator.TargetClassFilter.ALL, "TYPE");
1075 myResult = new ClassObjectEvaluator(new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(type)));
1080 public void visitNewExpression(PsiNewExpression expression) {
1081 PsiType expressionPsiType = expression.getType();
1082 if (expressionPsiType instanceof PsiArrayType) {
1083 Evaluator dimensionEvaluator = null;
1084 PsiExpression[] dimensions = expression.getArrayDimensions();
1085 if (dimensions.length == 1){
1086 PsiExpression dimensionExpression = dimensions[0];
1087 dimensionExpression.accept(this);
1088 if (myResult != null) {
1089 dimensionEvaluator = handleUnaryNumericPromotion(dimensionExpression.getType(), myResult);
1092 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
1093 DebuggerBundle.message("evaluation.error.invalid.array.dimension.expression", dimensionExpression.getText())));
1096 else if (dimensions.length > 1){
1097 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
1098 DebuggerBundle.message("evaluation.error.multi.dimensional.arrays.creation.not.supported"))
1102 Evaluator initializerEvaluator = null;
1103 PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer();
1104 if (arrayInitializer != null) {
1105 if (dimensionEvaluator != null) { // initializer already exists
1106 throw new EvaluateRuntimeException(EvaluateExceptionUtil
1107 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
1109 arrayInitializer.accept(this);
1110 if (myResult != null) {
1111 initializerEvaluator = handleUnaryNumericPromotion(arrayInitializer.getType(), myResult);
1114 throw new EvaluateRuntimeException(EvaluateExceptionUtil
1115 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", arrayInitializer.getText())));
1118 PsiExpression[] initializers = arrayInitializer.getInitializers();
1119 initializerEvaluators = new Evaluator[initializers.length];
1120 for (int idx = 0; idx < initializers.length; idx++) {
1121 PsiExpression initializer = initializers[idx];
1122 initializer.accept(this);
1123 if (myResult instanceof Evaluator) {
1124 initializerEvaluators[idx] = myResult;
1127 throw new EvaluateException("Invalid expression for array initializer: " + initializer.getText(), true);
1132 if (dimensionEvaluator == null && initializerEvaluator == null) {
1133 throw new EvaluateRuntimeException(EvaluateExceptionUtil
1134 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
1136 myResult = new NewArrayInstanceEvaluator(
1137 new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(expressionPsiType)),
1139 initializerEvaluator
1142 else { // must be a class ref
1143 LOG.assertTrue(expressionPsiType instanceof PsiClassType);
1144 PsiClass aClass = ((PsiClassType)expressionPsiType).resolve();
1145 if(aClass instanceof PsiAnonymousClass) {
1146 throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
1147 DebuggerBundle.message("evaluation.error.anonymous.class.evaluation.not.supported"))
1150 PsiExpressionList argumentList = expression.getArgumentList();
1151 if (argumentList == null) {
1152 throw new EvaluateRuntimeException(EvaluateExceptionUtil
1153 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
1155 PsiExpression[] argExpressions = argumentList.getExpressions();
1156 PsiMethod constructor = expression.resolveConstructor();
1157 if (constructor == null && argExpressions.length > 0) {
1158 throw new EvaluateRuntimeException(new EvaluateException(
1159 DebuggerBundle.message("evaluation.error.cannot.resolve.constructor", expression.getText()), null));
1161 Evaluator[] argumentEvaluators = new Evaluator[argExpressions.length];
1162 // evaluate arguments
1163 for (int idx = 0; idx < argExpressions.length; idx++) {
1164 PsiExpression argExpression = argExpressions[idx];
1165 argExpression.accept(this);
1166 if (myResult != null) {
1167 argumentEvaluators[idx] = myResult;
1170 throw new EvaluateRuntimeException(EvaluateExceptionUtil
1171 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", argExpression.getText())));
1174 //noinspection HardCodedStringLiteral
1175 JVMName signature = (constructor != null)? JVMNameUtil.getJVMSignature(constructor) : JVMNameUtil.getJVMRawText("()V");
1176 myResult = new NewClassInstanceEvaluator(
1177 new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(expressionPsiType)),
1185 public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) {
1186 PsiExpression[] initializers = expression.getInitializers();
1187 Evaluator[] evaluators = new Evaluator[initializers.length];
1188 for (int idx = 0; idx < initializers.length; idx++) {
1189 PsiExpression initializer = initializers[idx];
1190 initializer.accept(this);
1191 if (myResult != null) {
1192 evaluators[idx] = handleUnaryNumericPromotion(initializer.getType(), myResult);
1195 throw new EvaluateRuntimeException(EvaluateExceptionUtil
1196 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", initializer.getText())));
1199 myResult = new ArrayInitializerEvaluator(evaluators);
1202 private PsiClass getOuterClass(PsiClass aClass) {
1203 if(aClass == null) return null;
1204 return PsiTreeUtil.getContextOfType(aClass, PsiClass.class, true);
1207 private PsiClass getContainingClass(PsiVariable variable) {
1208 PsiElement element = PsiTreeUtil.getParentOfType(variable.getParent(), PsiClass.class, false);
1209 return element == null ? getContextPsiClass() : (PsiClass)element;
1212 public PsiClass getContextPsiClass() {
1213 return myContextPsiClass;
1216 protected ExpressionEvaluator buildElement(final PsiElement element) throws EvaluateException {
1217 LOG.assertTrue(element.isValid());
1219 myContextPsiClass = PsiTreeUtil.getContextOfType(element, PsiClass.class, false);
1221 element.accept(this);
1223 catch (EvaluateRuntimeException e) {
1226 if (myResult == null) {
1227 throw EvaluateExceptionUtil
1228 .createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", element.toString()));
1230 return new ExpressionEvaluatorImpl(myResult);