/src/main/java/com/kalessil/phpStorm/phpInspectionsEA/inspectors/apiUsage/strings/StringCaseManipulationInspector.java

https://github.com/kalessil/phpinspectionsea · Java · 116 lines · 95 code · 13 blank · 8 comment · 17 complexity · 1f61cbd5f3b96e215f2e014849813a57 MD5 · raw file

  1. package com.kalessil.phpStorm.phpInspectionsEA.inspectors.apiUsage.strings;
  2. import com.intellij.codeInspection.ProblemsHolder;
  3. import com.intellij.psi.PsiElement;
  4. import com.intellij.psi.PsiElementVisitor;
  5. import com.jetbrains.php.lang.psi.elements.FunctionReference;
  6. import com.kalessil.phpStorm.phpInspectionsEA.fixers.UseSuggestedReplacementFixer;
  7. import com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor;
  8. import com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection;
  9. import com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil;
  10. import com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiTypesUtil;
  11. import org.jetbrains.annotations.NotNull;
  12. import org.jetbrains.annotations.Nullable;
  13. import java.util.HashMap;
  14. import java.util.HashSet;
  15. import java.util.Map;
  16. import java.util.Set;
  17. /*
  18. * This file is part of the Php Inspections (EA Extended) package.
  19. *
  20. * (c) Vladimir Reznichenko <kalessil@gmail.com>
  21. *
  22. * For the full copyright and license information, please view the LICENSE
  23. * file that was distributed with this source code.
  24. */
  25. public class StringCaseManipulationInspector extends BasePhpInspection {
  26. private static final String messagePattern = "'%s' should be used instead.";
  27. private static final Map<String, String> functions = new HashMap<>();
  28. private static final Set<String> innerFunctions = new HashSet<>();
  29. static {
  30. functions.put("strpos", "stripos");
  31. functions.put("mb_strpos", "mb_stripos");
  32. functions.put("strrpos", "strripos");
  33. functions.put("mb_strrpos", "mb_strripos");
  34. innerFunctions.add("strtolower");
  35. innerFunctions.add("mb_strtolower");
  36. innerFunctions.add("strtoupper");
  37. innerFunctions.add("mb_strtoupper");
  38. }
  39. @NotNull
  40. @Override
  41. public String getShortName() {
  42. return "StringCaseManipulationInspection";
  43. }
  44. @NotNull
  45. @Override
  46. public String getDisplayName() {
  47. return "Unnecessary string case manipulation";
  48. }
  49. @Override
  50. @NotNull
  51. public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
  52. return new BasePhpElementVisitor() {
  53. @Override
  54. public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
  55. final String functionName = reference.getName();
  56. if (functionName != null && functions.containsKey(functionName)) {
  57. final PsiElement[] arguments = reference.getParameters();
  58. if (arguments.length == 2) {
  59. final PsiElement first = this.getSubject(arguments[0]);
  60. final PsiElement second = this.getSubject(arguments[1]);
  61. if (first != null || second != null) {
  62. final String replacement = "%f%(%a1%, %a2%)"
  63. .replace("%a2%", (second == null ? arguments[1] : second).getText())
  64. .replace("%a1%", (first == null ? arguments[0] : first).getText())
  65. .replace("%f%", functions.get(functionName));
  66. holder.registerProblem(
  67. reference,
  68. String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), replacement),
  69. new SimplifyFix(replacement)
  70. );
  71. }
  72. }
  73. }
  74. }
  75. @Nullable
  76. private PsiElement getSubject(@NotNull PsiElement expression) {
  77. PsiElement result = null;
  78. if (OpenapiTypesUtil.isFunctionReference(expression)) {
  79. final FunctionReference reference = (FunctionReference) expression;
  80. final String functionName = reference.getName();
  81. if (functionName != null && innerFunctions.contains(functionName)) {
  82. final PsiElement[] arguments = reference.getParameters();
  83. if (arguments.length == 1) {
  84. result = arguments[0];
  85. }
  86. }
  87. }
  88. return result;
  89. }
  90. };
  91. }
  92. private static final class SimplifyFix extends UseSuggestedReplacementFixer {
  93. private static final String title = "Simplify unnecessary case manipulation";
  94. @NotNull
  95. @Override
  96. public String getName() {
  97. return MessagesPresentationUtil.prefixWithEa(title);
  98. }
  99. SimplifyFix(@NotNull String expression) {
  100. super(expression);
  101. }
  102. }
  103. }