/*
 * Copyright 2000-2017 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.intellij.lang.regexp.inspection;

import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import org.intellij.lang.regexp.RegExpTT;
import org.intellij.lang.regexp.psi.RegExpBranch;
import org.intellij.lang.regexp.psi.RegExpChar;
import org.intellij.lang.regexp.psi.RegExpElementVisitor;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;

/**
 * @author Bas Leijdekkers
 */
public class EscapedMetaCharacterInspection extends LocalInspectionTool {

  @Nls
  @NotNull
  @Override
  public String getDisplayName() {
    return "Escaped meta character";
  }

  @NotNull
  @Override
  public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
    return new EscapedMetaCharacterVisitor(holder);
  }

  private static class EscapedMetaCharacterVisitor extends RegExpElementVisitor {

    private final ProblemsHolder myHolder;

    public EscapedMetaCharacterVisitor(ProblemsHolder holder) {
      myHolder = holder;
    }

    @Override
    public void visitRegExpChar(RegExpChar ch) {
      if (ch.getType() != RegExpChar.Type.CHAR) {
        return;
      }
      final String text = ch.getUnescapedText();
      if (text.length() != 2 || text.charAt(0) != '\\') {
        return;
      }
      final char c = text.charAt(1);
      switch (c) {
        case '{':
        case '}':
        case '(':
        case ')':
        case '.':
        case '*':
        case '+':
        case '?':
        case '|':
        case '$':
          final ASTNode node = ch.getNode().getFirstChildNode();
          if (node != null && node.getElementType() == RegExpTT.REDUNDANT_ESCAPE) {
            return;
          }
          myHolder.registerProblem(ch, "Escaped meta character <code>" + c + "</code>", new EscapedMetaCharacterFix(c));
          break;
      }
    }
  }

  private static class EscapedMetaCharacterFix implements LocalQuickFix {

    private final char myC;

    EscapedMetaCharacterFix(char c) {
      myC = c;
    }

    @Nls
    @NotNull
    @Override
    public String getName() {
      return "Replace with '[" + myC + "]'";
    }

    @Nls
    @NotNull
    @Override
    public String getFamilyName() {
      return "Replace with character inside class";
    }

    @Override
    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
      final PsiElement element = descriptor.getPsiElement();
      if (!(element instanceof RegExpChar)) {
        return;
      }
      final RegExpBranch branch = RegExpFactory.createBranchFromText("[" + myC + ']', element);
      element.replace(branch.getFirstChild());
    }
  }
}

@@ -2217,211 +2217,73 @@
     
-switch (c) %7B%0A        case '%7B':%0A        case '%7D':%0A        case '(':%0A        case ')':%0A        case '.':%0A        case '*':%0A        case '+':%0A        case '?':%0A        case '%7C':%0A        case '$':%0A  
+if (%22%7B%7D().*+?%7C$%22.indexOf(c) %3C 0) %7B%0A        return;%0A      %7D%0A
       
-  
 fina
@@ -2333,20 +2333,16 @@
 Node();%0A
-    
       if
@@ -2417,36 +2417,32 @@
 ) %7B%0A        
-    
 return;%0A
           %7D%0A
@@ -2429,20 +2429,16 @@
 return;%0A
-    
       %7D%0A
@@ -2443,20 +2443,16 @@
 %7D%0A      
-    
 myHolder
@@ -2558,33 +2558,8 @@
 ));%0A
-          break;%0A      %7D%0A
     

replace switch statement with simple if