/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ObjectAllocationInLoopInspection.java

https://bitbucket.org/nbargnesi/idea
Java | 130 lines | 107 code | 8 blank | 15 comment | 20 complexity | 2ae203595c1c7f7fefe2479987640702 MD5 | raw file
  1. /*
  2. * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
  3. *
  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
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  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.
  15. */
  16. package com.siyeh.ig.performance;
  17. import com.intellij.psi.*;
  18. import com.intellij.psi.util.PsiTreeUtil;
  19. import com.siyeh.InspectionGadgetsBundle;
  20. import com.siyeh.ig.BaseInspection;
  21. import com.siyeh.ig.BaseInspectionVisitor;
  22. import com.siyeh.ig.psiutils.ControlFlowUtils;
  23. import org.jetbrains.annotations.NotNull;
  24. public class ObjectAllocationInLoopInspection extends BaseInspection {
  25. @NotNull
  26. public String getDisplayName() {
  27. return InspectionGadgetsBundle.message(
  28. "object.allocation.in.loop.display.name");
  29. }
  30. @NotNull
  31. protected String buildErrorString(Object... infos) {
  32. return InspectionGadgetsBundle.message(
  33. "object.allocation.in.loop.problem.descriptor");
  34. }
  35. public BaseInspectionVisitor buildVisitor() {
  36. return new ObjectAllocationInLoopsVisitor();
  37. }
  38. private static class ObjectAllocationInLoopsVisitor
  39. extends BaseInspectionVisitor {
  40. @Override
  41. public void visitNewExpression(@NotNull PsiNewExpression expression) {
  42. super.visitNewExpression(expression);
  43. if (!ControlFlowUtils.isInLoop(expression)) {
  44. return;
  45. }
  46. if (ControlFlowUtils.isInExitStatement(expression)) {
  47. return;
  48. }
  49. final PsiStatement newExpressionStatement =
  50. PsiTreeUtil.getParentOfType(expression, PsiStatement.class);
  51. if (newExpressionStatement == null) {
  52. return;
  53. }
  54. final PsiStatement parentStatement =
  55. PsiTreeUtil.getParentOfType(newExpressionStatement,
  56. PsiStatement.class);
  57. if (!ControlFlowUtils.statementMayCompleteNormally(
  58. parentStatement)) {
  59. return;
  60. }
  61. if (isAllocatedOnlyOnce(expression)) {
  62. return;
  63. }
  64. registerError(expression);
  65. }
  66. private static boolean isAllocatedOnlyOnce(
  67. PsiNewExpression expression) {
  68. final PsiElement parent = expression.getParent();
  69. if (!(parent instanceof PsiAssignmentExpression)) {
  70. return false;
  71. }
  72. final PsiAssignmentExpression assignmentExpression =
  73. (PsiAssignmentExpression)parent;
  74. final PsiExpression lExpression =
  75. assignmentExpression.getLExpression();
  76. if (!(lExpression instanceof PsiReferenceExpression)) {
  77. return false;
  78. }
  79. final PsiIfStatement ifStatement =
  80. PsiTreeUtil.getParentOfType(assignmentExpression,
  81. PsiIfStatement.class);
  82. if (ifStatement == null) {
  83. return false;
  84. }
  85. final PsiExpression condition = ifStatement.getCondition();
  86. if (!(condition instanceof PsiBinaryExpression)) {
  87. return false;
  88. }
  89. final PsiBinaryExpression binaryExpression =
  90. (PsiBinaryExpression)condition;
  91. if (binaryExpression.getOperationTokenType() !=
  92. JavaTokenType.EQEQ) {
  93. return false;
  94. }
  95. final PsiReferenceExpression referenceExpression =
  96. (PsiReferenceExpression)lExpression;
  97. final PsiExpression lhs = binaryExpression.getLOperand();
  98. final PsiExpression rhs = binaryExpression.getROperand();
  99. if (lhs instanceof PsiLiteralExpression) {
  100. if (!"null".equals(lhs.getText())) {
  101. return false;
  102. }
  103. if (!(rhs instanceof PsiReferenceExpression)) {
  104. return false;
  105. }
  106. return referenceExpression.getText().equals(rhs.getText());
  107. }
  108. else if (rhs instanceof PsiLiteralExpression) {
  109. if (!"null".equals(rhs.getText())) {
  110. return false;
  111. }
  112. if (!(lhs instanceof PsiReferenceExpression)) {
  113. return false;
  114. }
  115. return referenceExpression.getText().equals(lhs.getText());
  116. }
  117. else {
  118. return false;
  119. }
  120. }
  121. }
  122. }