package com.intellij.codeInspection;

import com.intellij.analysis.AnalysisScope;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInspection.reference.RefElement;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiRecursiveElementVisitor;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;

/**
 * @author yole
 */
public class SyntaxErrorInspection extends GlobalInspectionTool {
  @Override
  public boolean isGraphNeeded() {
    return false;
  }

  @NotNull
  @Override
  public HighlightDisplayLevel getDefaultLevel() {
    return HighlightDisplayLevel.ERROR;
  }

  @Override
  public void runInspection(AnalysisScope scope,
                            final InspectionManager manager,
                            final GlobalInspectionContext globalContext,
                            final ProblemDescriptionsProcessor problemDescriptionsProcessor) {
    scope.accept(new PsiRecursiveElementVisitor() {
      @Override
      public void visitErrorElement(PsiErrorElement element) {
        super.visitErrorElement(element);
        CommonProblemDescriptor descriptor;
        final TextRange textRange = element.getTextRange();
        if (textRange.getLength() > 0) {
          descriptor = manager.createProblemDescriptor(element, element.getErrorDescription(), ProblemHighlightType.ERROR, null);
        }
        else {
          PsiElement parent = element;
          do {
            parent = parent.getParent();
          } while(parent != null && parent.getTextRange().getLength() == 0);
          if (parent == null) return;
          int offset = element.getTextRange().getStartOffset() - parent.getTextRange().getStartOffset();
          descriptor = manager.createProblemDescriptor(parent,
                                                       new TextRange(offset, offset+1),
                                                       element.getErrorDescription(), ProblemHighlightType.ERROR);
        }

        final RefElement refElement = globalContext.getRefManager().getReference(element.getContainingFile());
        problemDescriptionsProcessor.addProblemElement(refElement, descriptor);
      }
    });
  }

  @Nls
  @NotNull
  @Override
  public String getGroupDisplayName() {
    return "General";
  }

  @Nls
  @NotNull
  @Override
  public String getDisplayName() {
    return "Syntax error";
  }

  @NotNull
  @Override
  public String getShortName() {
    return "SyntaxError";
  }
}

@@ -1541,10 +1541,19 @@
     
-do
+while(true)
  %7B%0A 
@@ -1606,23 +1606,21 @@
     
-%7D while
+  if 
 (parent 
 != n
@@ -1619,40 +1619,173 @@
 ent 
-!
+=
 = null
- && parent.getTextRange()
+) break;%0A            TextRange r = parent.getTextRange();%0A            if (r == null) return; // no place to attach the problem descriptor to%0A            if (r
 .get
@@ -1797,14 +1797,61 @@
 h() 
-== 0);
+%3E 0) %7B%0A              break;%0A            %7D%0A          %7D
 %0A   

fix NPE in SyntaxErrorInspection (IDEADEV-39101)