From 9886c29eade39f5766ddd2defa83eb3c0f9bebf7 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 23 May 2012 21:48:48 +0200 Subject: [PATCH] IDEA-85926 ('Compute constant value' intention shouldn't be applied in right-associative manner) and fix the intentions in the presence of polyadic expressions --- .../siyeh/IntentionPowerPackBundle.properties | 3 +- .../constant/ConstantExpressionIntention.java | 33 +-- .../constant/ConstantExpressionPredicate.java | 33 +-- .../ConstantSubexpressionIntention.java | 195 +++++++++--------- .../ConstantSubexpressionPredicate.java | 96 ++++----- .../com/siyeh/ipp/psiutils/HighlightUtil.java | 62 +++--- 6 files changed, 216 insertions(+), 206 deletions(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties index d9759cd5802e..41d59b6dc7a3 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties +++ b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties @@ -37,7 +37,6 @@ replace.switch.with.if.intention.name=Replace 'switch' with 'if' replace.switch.with.if.intention.family.name=Replace Switch with If simplify.variable.intention.name=Replace with Java-style array declaration simplify.variable.intention.family.name=Replace with Java Style Array Declaration -constant.expression.intention.name=Compute constant value constant.expression.intention.family.name=Compute Constant Value create.assert.intention.name=Create JUnit Assertion create.assert.intention.family.name=Create JUnit Assertion @@ -176,7 +175,7 @@ add.braces.intention.name=Add Braces to ''{0}'' statement remove.braces.intention.name=Remove braces from ''{0}'' statement flip.commutative.method.call.intention.name=Flip ''.{0}()'' flip.commutative.method.call.intention.name1=Flip ''.{0}()'' (may change semantics) -constant.subexpression.intention.name=Compute constant value of ''{0}'' +constant.expression.intention.name=Compute constant value of ''{0}'' status.bar.escape.highlighting.message=Press Escape to remove the highlighting 1.fully.qualified.name.status.bar.escape.highlighting.message=1 fully qualified name replaced with import (press Escape to remove highlighting) multiple.fully.qualified.names.status.bar.escape.highlighting.message={0} fully qualified names replaced with import (press Escape to remove highlighting) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionIntention.java index ba3e54e0f2b9..4c597df5d2ba 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,15 +16,24 @@ package com.siyeh.ipp.constant; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; import com.intellij.util.IncorrectOperationException; -import com.siyeh.ipp.base.Intention; +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.base.MutablyNamedIntention; import com.siyeh.ipp.base.PsiElementPredicate; import com.siyeh.ipp.psiutils.ExpressionUtils; +import com.siyeh.ipp.psiutils.HighlightUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -public class ConstantExpressionIntention extends Intention { +public class ConstantExpressionIntention extends MutablyNamedIntention { + + @Override + protected String getTextForElement(PsiElement element) { + final String text = HighlightUtil.getPresentableText(element); + return IntentionPowerPackBundle.message("constant.expression.intention.name", text); + } @Override @NotNull @@ -33,22 +42,16 @@ public class ConstantExpressionIntention extends Intention { } @Override - public void processIntention(PsiElement element) - throws IncorrectOperationException { - final PsiExpression expression = - (PsiExpression)element; - final Object value = - ExpressionUtils.computeConstantExpression(expression); + public void processIntention(PsiElement element) throws IncorrectOperationException { + final PsiExpression expression = (PsiExpression)element; + final Object value = ExpressionUtils.computeConstantExpression(expression); @NonNls final String newExpression; if (value instanceof String) { final String string = (String)value; - newExpression = - '"' + StringUtil.escapeStringCharacters(string) + '"'; + newExpression = '"' + StringUtil.escapeStringCharacters(string) + '"'; } else if (value instanceof Character) { - newExpression = - '\'' + StringUtil.escapeStringCharacters(value.toString()) + - '\''; + newExpression = '\'' + StringUtil.escapeStringCharacters(value.toString()) + '\''; } else if (value instanceof Long) { newExpression = value.toString() + 'L'; diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java index 53a5fc14acdf..73d7335e87d1 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,28 +24,34 @@ import com.siyeh.ipp.psiutils.ExpressionUtils; class ConstantExpressionPredicate implements PsiElementPredicate { public boolean satisfiedBy(PsiElement element) { - if (!(element instanceof PsiBinaryExpression)) { + if (!(element instanceof PsiPolyadicExpression)) { return false; } - if (element instanceof PsiLiteralExpression || - element instanceof PsiClassObjectAccessExpression) { + if (element instanceof PsiLiteralExpression || element instanceof PsiClassObjectAccessExpression) { return false; } - final PsiBinaryExpression expression = (PsiBinaryExpression)element; - final PsiExpression rhs = expression.getROperand(); - if (rhs == null) { + final PsiPolyadicExpression expression = (PsiPolyadicExpression)element; + final PsiType expressionType = expression.getType(); + if (expressionType.equalsToText("java.lang.String")) { + // intention disabled for string concatenations because of performance issues on + // relatively common large string expressions. return false; } - final PsiType type = rhs.getType(); - if (type == null || type.equalsToText("java.lang.String")) { - return false; + final PsiExpression[] operands = expression.getOperands(); + for (PsiExpression operand : operands) { + if (operand == null) { + return false; + } + final PsiType type = operand.getType(); + if (type == null || type.equalsToText("java.lang.String")) { + return false; + } } if (!PsiUtil.isConstantExpression(expression)) { return false; } try { - final Object value = - ExpressionUtils.computeConstantExpression(expression, true); + final Object value = ExpressionUtils.computeConstantExpression(expression, true); if (value == null) { return false; } @@ -54,7 +60,6 @@ class ConstantExpressionPredicate implements PsiElementPredicate { return false; } final PsiElement parent = element.getParent(); - return !(parent instanceof PsiExpression && - PsiUtil.isConstantExpression((PsiExpression)parent)); + return !(parent instanceof PsiExpression) || !PsiUtil.isConstantExpression((PsiExpression)parent); } } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionIntention.java index d638fc6a4ecf..3b02069a5913 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,17 +15,13 @@ */ package com.siyeh.ipp.constant; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiBinaryExpression; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiExpression; -import com.intellij.psi.PsiJavaToken; +import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; import com.siyeh.IntentionPowerPackBundle; import com.siyeh.ipp.base.MutablyNamedIntention; import com.siyeh.ipp.base.PsiElementPredicate; -import com.siyeh.ipp.psiutils.ConcatenationUtils; import com.siyeh.ipp.psiutils.ExpressionUtils; +import com.siyeh.ipp.psiutils.HighlightUtil; import org.jetbrains.annotations.NotNull; public class ConstantSubexpressionIntention extends MutablyNamedIntention { @@ -38,108 +34,109 @@ public class ConstantSubexpressionIntention extends MutablyNamedIntention { @Override protected String getTextForElement(PsiElement element) { - final PsiBinaryExpression binaryExpression = - (PsiBinaryExpression)element.getParent(); - assert binaryExpression != null; - final PsiExpression lhs = binaryExpression.getLOperand(); - final PsiExpression leftSide; - if (lhs instanceof PsiBinaryExpression) { - final PsiBinaryExpression lhsBinaryExpression = - (PsiBinaryExpression)lhs; - leftSide = lhsBinaryExpression.getROperand(); + final PsiJavaToken token; + if (element instanceof PsiJavaToken) { + token = (PsiJavaToken)element; + } else { + final PsiElement prevSibling = element.getPrevSibling(); + if (prevSibling instanceof PsiJavaToken) { + token = (PsiJavaToken)prevSibling; + } else { + throw new AssertionError(); + } } - else { - leftSide = lhs; - } - final PsiJavaToken operationSign = binaryExpression.getOperationSign(); - final PsiExpression rhs = binaryExpression.getROperand(); - assert rhs != null; - assert leftSide != null; - return IntentionPowerPackBundle.message( - "constant.subexpression.intention.name", leftSide.getText() + - ' ' + operationSign.getText() + ' ' + rhs.getText()); + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)element.getParent(); + final PsiPolyadicExpression subexpression = ConstantSubexpressionPredicate.getSubexpression(polyadicExpression, token); + final String text = HighlightUtil.getPresentableText(subexpression); + return IntentionPowerPackBundle.message("constant.expression.intention.name", text); } @Override - public void processIntention(@NotNull PsiElement element) - throws IncorrectOperationException { - final PsiExpression expression = (PsiExpression)element.getParent(); - assert expression != null; - String newExpression = ""; - final Object constantValue; - if (expression instanceof PsiBinaryExpression) { - final PsiBinaryExpression copy = - (PsiBinaryExpression)expression.copy(); - final PsiExpression lhs = copy.getLOperand(); - if (lhs instanceof PsiBinaryExpression) { - final PsiBinaryExpression lhsBinaryExpression = - (PsiBinaryExpression)lhs; - newExpression += getLeftSideText(lhsBinaryExpression); - final PsiExpression rightSide = - lhsBinaryExpression.getROperand(); - assert rightSide != null; - lhs.replace(rightSide); - } - if (ConcatenationUtils.isConcatenation(expression)) { - constantValue = computeConstantStringExpression(copy); - } - else { - constantValue = - ExpressionUtils.computeConstantExpression(copy); + public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + final PsiJavaToken token; + if (element instanceof PsiJavaToken) { + token = (PsiJavaToken)element; + } else { + final PsiElement prevSibling = element.getPrevSibling(); + if (prevSibling instanceof PsiJavaToken) { + token = (PsiJavaToken)prevSibling; + } else { + throw new AssertionError(); } } - else { - constantValue = - ExpressionUtils.computeConstantExpression(expression); - } - if (constantValue instanceof String) { - newExpression += '"' + StringUtil.escapeStringCharacters( - constantValue.toString()) + '"'; - } - else if (constantValue != null) { - if (constantValue instanceof Number) { - final Number number = (Number)constantValue; - if (0 > number.doubleValue()) { - newExpression += " "; + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)element.getParent(); + final PsiPolyadicExpression subexpression = ConstantSubexpressionPredicate.getSubexpression(polyadicExpression, token); + final Object value = ExpressionUtils.computeConstantExpression(subexpression); + final StringBuilder newExpressionText = new StringBuilder(); + final PsiExpression[] operands = polyadicExpression.getOperands(); + PsiExpression prevOperand = null; + PsiJavaToken prevToken = null; + for (PsiExpression operand : operands) { + final PsiJavaToken currentToken = polyadicExpression.getTokenBeforeOperand(operand); + if (token == currentToken) { + if (prevToken != null) { + newExpressionText.append(prevToken.getText()); } + if (newExpressionText.length() > 0) { + newExpressionText.append(' '); + } + if (value instanceof Long) { + newExpressionText.append(value).append('L'); + } else if (value instanceof Double) { + final double v = ((Double)value).doubleValue(); + if (Double.isNaN(v)) { + newExpressionText.append("java.lang.Double.NaN"); + } + else if (Double.isInfinite(v)) { + if (v > 0.0) { + newExpressionText.append("java.lang.Double.POSITIVE_INFINITY"); + } + else { + newExpressionText.append("java.lang.Double.NEGATIVE_INFINITY"); + } + } + else { + newExpressionText.append(Double.toString(v)); + } + } + else if (value instanceof Float) { + final float v = ((Float)value).floatValue(); + if (Float.isNaN(v)) { + newExpressionText.append("java.lang.Float.NaN"); + } + else if (Float.isInfinite(v)) { + if (v > 0.0F) { + newExpressionText.append("java.lang.Float.POSITIVE_INFINITY"); + } + else { + newExpressionText.append("java.lang.Float.NEGATIVE_INFINITY"); + } + } + else { + newExpressionText.append(Float.toString(v)).append('f'); + } + } else { + newExpressionText.append(value); + } + prevOperand = null; + prevToken = null; + } else { + if (prevToken != null) { + newExpressionText.append(prevToken.getText()); + } + if (prevOperand != null) { + newExpressionText.append(prevOperand.getText()); + } + prevOperand = operand; + prevToken = currentToken; } - newExpression += constantValue.toString(); } - replaceExpression(newExpression, expression); - } - - /** - * handles the specified expression as if it was part of a string expression - * (even if it's of another type) and computes a constant string expression - * from it. - */ - private static String computeConstantStringExpression( - PsiBinaryExpression expression) { - final PsiExpression lhs = expression.getLOperand(); - final String lhsText = lhs.getText(); - String result; - if (lhsText.charAt(0) == '\'' || lhsText.charAt(0) == '"') { - result = lhsText.substring(1, lhsText.length() - 1); + if (prevToken != null) { + newExpressionText.append(prevToken.getText()); } - else { - result = lhsText; + if (prevOperand != null) { + newExpressionText.append(prevOperand.getText()); } - final PsiExpression rhs = expression.getROperand(); - assert rhs != null; - final String rhsText = rhs.getText(); - if (rhsText.charAt(0) == '\'' || rhsText.charAt(0) == '"') { - result += rhsText.substring(1, rhsText.length() - 1); - } - else { - result += rhsText; - } - return result; - } - - private static String getLeftSideText( - PsiBinaryExpression binaryExpression) { - final PsiExpression lhs = binaryExpression.getLOperand(); - final PsiJavaToken sign = binaryExpression.getOperationSign(); - return lhs.getText() + sign.getText(); + replaceExpression(newExpressionText.toString(), polyadicExpression); } } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java index bbe065227f63..02d111224d3b 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,47 +19,71 @@ import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; import com.siyeh.ipp.base.PsiElementPredicate; import com.siyeh.ipp.psiutils.ExpressionUtils; -import org.jetbrains.annotations.Nullable; class ConstantSubexpressionPredicate implements PsiElementPredicate { public boolean satisfiedBy(PsiElement element) { - if (!(element instanceof PsiJavaToken) && - !(element.getPrevSibling() instanceof PsiJavaToken)) { - return false; + final PsiJavaToken token; + if (element instanceof PsiJavaToken) { + token = (PsiJavaToken)element; } + else { + final PsiElement prevSibling = element.getPrevSibling(); + if (prevSibling instanceof PsiJavaToken) { + token = (PsiJavaToken)prevSibling; + } + else { + return false; + } + } + final PsiElement parent = element.getParent(); - if (!(parent instanceof PsiBinaryExpression)) { + if (!(parent instanceof PsiPolyadicExpression)) { return false; } - final PsiBinaryExpression binaryExpression = - (PsiBinaryExpression)parent; - final PsiType type = binaryExpression.getType(); + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)parent; + final PsiType type = polyadicExpression.getType(); if (type == null || type.equalsToText("java.lang.String")) { // handled by JoinConcatenatedStringLiteralsIntention return false; } - final PsiBinaryExpression subexpression = - getSubexpression(binaryExpression); + final PsiPolyadicExpression subexpression = getSubexpression(polyadicExpression, token); if (subexpression == null) { return false; } - if (binaryExpression.equals(subexpression) && - !isPartOfConstantExpression(binaryExpression)) { - // handled by ConstantExpressonIntention + if (!isPartOfLargerExpression(polyadicExpression)) { + // handled by ConstantExpressionIntention return false; } if (!PsiUtil.isConstantExpression(subexpression)) { return false; } - final Object value = - ExpressionUtils.computeConstantExpression(subexpression); + final Object value = ExpressionUtils.computeConstantExpression(subexpression); return value != null; } - private static boolean isPartOfConstantExpression( - PsiBinaryExpression binaryExpression) { - final PsiElement containingElement = binaryExpression.getParent(); + static PsiPolyadicExpression getSubexpression(PsiPolyadicExpression expression, PsiJavaToken token) { + final PsiExpression[] operands = expression.getOperands(); + if (operands.length == 2) { + return expression; + } + for (int i = 1; i < operands.length; i++) { + final PsiExpression operand = operands[i]; + final PsiJavaToken currentToken = expression.getTokenBeforeOperand(operand); + if (currentToken == token) { + final String binaryExpressionText = operands[i - 1].getText() + ' ' + token.getText() + ' ' + operand.getText(); + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(expression.getProject()); + return (PsiBinaryExpression)factory.createExpressionFromText(binaryExpressionText, expression); + } + } + return null; + } + + private static boolean isPartOfLargerExpression(PsiPolyadicExpression expression) { + if (expression.getOperands().length > 2) { + return true; + } + final PsiElement containingElement = expression.getParent(); if (containingElement instanceof PsiExpression) { final PsiExpression containingExpression = (PsiExpression)containingElement; @@ -72,38 +96,4 @@ class ConstantSubexpressionPredicate implements PsiElementPredicate { } return true; } - - /** - * Returns the smallest subexpression (if precendence allows it). example: - * variable + 2 + 3 normally gets evaluated left to right -> (variable + 2) - * + 3 this method returns the right most legal subexpression -> 2 + 3 - */ - @Nullable - private static PsiBinaryExpression getSubexpression( - PsiBinaryExpression expression) { - final PsiExpression rhs = expression.getROperand(); - if (rhs == null) { - return null; - } - final PsiExpression lhs = expression.getLOperand(); - if (!(lhs instanceof PsiBinaryExpression)) { - return expression; - } - final PsiBinaryExpression lhsBinaryExpression = - (PsiBinaryExpression)lhs; - final PsiExpression leftSide = lhsBinaryExpression.getROperand(); - if (leftSide == null) { - return null; - } - try { - final PsiBinaryExpression binaryExpression = - (PsiBinaryExpression)expression.copy(); - final PsiExpression lOperand = binaryExpression.getLOperand(); - lOperand.replace(leftSide); - return binaryExpression; - } - catch (Throwable ignore) { - return null; - } - } } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/HighlightUtil.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/HighlightUtil.java index c7350f7cce1a..e03c5c876868 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/HighlightUtil.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/HighlightUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2007-2011 Bas Leijdekkers + * Copyright 2007-2012 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiUtilBase; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.util.PsiUtilCore; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -51,32 +52,24 @@ public class HighlightUtil { final Application application = ApplicationManager.getApplication(); application.invokeLater(new Runnable() { public void run() { - final PsiElement[] elements = - PsiUtilBase.toPsiElementArray(elementCollection); + final PsiElement[] elements = PsiUtilCore.toPsiElementArray(elementCollection); final PsiElement firstElement = elements[0]; if (!firstElement.isValid()) { return; } final Project project = firstElement.getProject(); - final FileEditorManager editorManager = - FileEditorManager.getInstance(project); - final EditorColorsManager editorColorsManager = - EditorColorsManager.getInstance(); + final FileEditorManager editorManager = FileEditorManager.getInstance(project); + final EditorColorsManager editorColorsManager = EditorColorsManager.getInstance(); final Editor editor = editorManager.getSelectedTextEditor(); if (editor == null) { return; } - final EditorColorsScheme globalScheme = - editorColorsManager.getGlobalScheme(); - final TextAttributes textattributes = - globalScheme.getAttributes( + final EditorColorsScheme globalScheme = editorColorsManager.getGlobalScheme(); + final TextAttributes textattributes = globalScheme.getAttributes( EditorColors.SEARCH_RESULT_ATTRIBUTES); - final HighlightManager highlightManager = - HighlightManager.getInstance(project); - highlightManager.addOccurrenceHighlights( - editor, elements, textattributes, true, null); - final FindManager findmanager = - FindManager.getInstance(project); + final HighlightManager highlightManager = HighlightManager.getInstance(project); + highlightManager.addOccurrenceHighlights(editor, elements, textattributes, true, null); + final FindManager findmanager = FindManager.getInstance(project); FindModel findmodel = findmanager.getFindNextModel(); if (findmodel == null) { findmodel = findmanager.getFindInFileModel(); @@ -86,11 +79,11 @@ public class HighlightUtil { findmanager.setFindNextModel(findmodel); application.invokeLater(new Runnable() { public void run() { - final WindowManager windowManager = - WindowManager.getInstance(); - final StatusBar statusBar = - windowManager.getStatusBar(project); - statusBar.setInfo(statusBarText); + final WindowManager windowManager = WindowManager.getInstance(); + final StatusBar statusBar = windowManager.getStatusBar(project); + if (statusBar != null) { + statusBar.setInfo(statusBarText); + } } }); } @@ -102,4 +95,27 @@ public class HighlightUtil { final List elements = Collections.singletonList(element); highlightElements(elements, statusBarText); } + + public static String getPresentableText(PsiElement element) { + return getPresentableText(element, new StringBuilder()).toString(); + } + + private static StringBuilder getPresentableText(PsiElement element, StringBuilder builder) { + if (element == null) { + return builder; + } + if (element instanceof PsiWhiteSpace) { + return builder.append(' '); + } + final PsiElement[] children = element.getChildren(); + if (children.length != 0) { + for (PsiElement child : children) { + getPresentableText(child, builder); + } + } + else { + builder.append(element.getText()); + } + return builder; + } } \ No newline at end of file