<commit_before>// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.

package com.intellij.codeInsight.generation;

import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.CommentUtil;
import com.intellij.codeInsight.actions.MultiCaretCodeInsightActionHandler;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.formatting.IndentData;
import com.intellij.ide.highlighter.custom.SyntaxTable;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.lang.Commenter;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageCommenters;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.impl.AbstractFileType;
import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.impl.source.tree.injected.InjectedCaret;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.DocumentUtil;
import com.intellij.util.containers.IntArrayList;
import com.intellij.util.text.CharArrayUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class CommentByLineCommentHandler extends MultiCaretCodeInsightActionHandler {

  private static final Key<Boolean> INJECTION_FORBIDS_LINE_COMMENTS = Key.create("INJECTION_FORBIDS_LINE_COMMENTS");

  /**
   * Disable line commenting in an injected file making this action operate on its host file instead.
   *
   * @param file injected file where line comment action shouldn't be available
   */
  public static void markInjectedFileUnsuitableForLineComment(@NotNull PsiFile file) {
    if (!InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file)) {
      throw new IllegalArgumentException("This method should be called only on injected files");
    }

    file.putUserData(INJECTION_FORBIDS_LINE_COMMENTS, true);
  }

  private final List<Block> myBlocks = new ArrayList<>();

  @Override
  // first pass - adjacent carets are grouped into blocks
  public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull Caret caret, @NotNull PsiFile file) {
    file = file.getViewProvider().getPsi(file.getViewProvider().getBaseLanguage());

    PsiElement context = InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file);

    if (context != null && shouldCommentInHostFile(file, context)) {
      file = context.getContainingFile();
      editor = editor instanceof EditorWindow ? ((EditorWindow)editor).getDelegate() : editor;
      caret = caret instanceof InjectedCaret ? ((InjectedCaret)caret).getDelegate() : caret;
    }

    Document document = editor.getDocument();
    boolean hasSelection = caret.hasSelection();
    int startOffset = caret.getSelectionStart();
    int endOffset = caret.getSelectionEnd();

    FoldRegion fold = editor.getFoldingModel().getCollapsedRegionAtOffset(startOffset);
    if (fold != null && fold.shouldNeverExpand() && fold.getStartOffset() == startOffset && fold.getEndOffset() == endOffset) {
      // Foldings that never expand are automatically selected, so the fact it is selected must not interfere with commenter's logic
      hasSelection = false;
    }

    if (document.getTextLength() == 0) return;

    while (true) {
      int firstLineStart = DocumentUtil.getLineStartOffset(startOffset, document);
      FoldRegion collapsedAt = editor.getFoldingModel().getCollapsedRegionAtOffset(firstLineStart - 1);
      if (collapsedAt == null) break;
      int regionStartOffset = collapsedAt.getStartOffset();
      if (regionStartOffset >= startOffset) break;
      startOffset = regionStartOffset;
    }
    while (true) {
      int lastLineEnd = DocumentUtil.getLineEndOffset(endOffset, document);
      FoldRegion collapsedAt = editor.getFoldingModel().getCollapsedRegionAtOffset(lastLineEnd);
      if (collapsedAt == null) break;
      int regionEndOffset = collapsedAt.getEndOffset();
      if (regionEndOffset <= endOffset) break;
      endOffset = regionEndOffset;
    }
<commit_msg>IDEA-200630 too eager commenting out<commit_after>// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.

package com.intellij.codeInsight.generation;

import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.CommentUtil;
import com.intellij.codeInsight.actions.MultiCaretCodeInsightActionHandler;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.formatting.IndentData;
import com.intellij.ide.highlighter.custom.SyntaxTable;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.lang.Commenter;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageCommenters;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.impl.AbstractFileType;
import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.impl.source.tree.injected.InjectedCaret;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.DocumentUtil;
import com.intellij.util.containers.IntArrayList;
import com.intellij.util.text.CharArrayUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class CommentByLineCommentHandler extends MultiCaretCodeInsightActionHandler {

  private static final Key<Boolean> INJECTION_FORBIDS_LINE_COMMENTS = Key.create("INJECTION_FORBIDS_LINE_COMMENTS");

  /**
   * Disable line commenting in an injected file making this action operate on its host file instead.
   *
   * @param file injected file where line comment action shouldn't be available
   */
  public static void markInjectedFileUnsuitableForLineComment(@NotNull PsiFile file) {
    if (!InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file)) {
      throw new IllegalArgumentException("This method should be called only on injected files");
    }

    file.putUserData(INJECTION_FORBIDS_LINE_COMMENTS, true);
  }

  private final List<Block> myBlocks = new ArrayList<>();

  @Override
  // first pass - adjacent carets are grouped into blocks
  public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull Caret caret, @NotNull PsiFile file) {
    file = file.getViewProvider().getPsi(file.getViewProvider().getBaseLanguage());

    PsiElement context = InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file);

    if (context != null && shouldCommentInHostFile(file, context)) {
      file = context.getContainingFile();
      editor = editor instanceof EditorWindow ? ((EditorWindow)editor).getDelegate() : editor;
      caret = caret instanceof InjectedCaret ? ((InjectedCaret)caret).getDelegate() : caret;
    }

    Document document = editor.getDocument();
    boolean hasSelection = caret.hasSelection();
    int startOffset = caret.getSelectionStart();
    int endOffset = caret.getSelectionEnd();

    FoldRegion fold = editor.getFoldingModel().getCollapsedRegionAtOffset(startOffset);
    if (fold != null && fold.shouldNeverExpand() && fold.getStartOffset() == startOffset && fold.getEndOffset() == endOffset) {
      // Foldings that never expand are automatically selected, so the fact it is selected must not interfere with commenter's logic
      hasSelection = false;
    }

    if (document.getTextLength() == 0) return;

    while (true) {
      int firstLineStart = DocumentUtil.getLineStartOffset(startOffset, document);
      FoldRegion collapsedAt = editor.getFoldingModel().getCollapsedRegionAtOffset(firstLineStart - 1);
      if (collapsedAt == null) break;
      int regionStartOffset = collapsedAt.getStartOffset();
      if (regionStartOffset >= startOffset) break;
      startOffset = regionStartOffset;
    }
    if (!hasSelection || !DocumentUtil.isAtLineStart(endOffset, document)) {
      while (true) {
        int lastLineEnd = DocumentUtil.getLineEndOffset(endOffset, document);
        FoldRegion collapsedAt = editor.getFoldingModel().getCollapsedRegionAtOffset(lastLineEnd);
        if (collapsedAt == null) break;
        int regionEndOffset = collapsedAt.getEndOffset();
        if (regionEndOffset <= endOffset) break;
        endOffset = regionEndOffset;
      }
    }

{'fraction_non_alphanumeric': 0.09688684893234883, 'fraction_numerical': 0.0029934144881261227, 'mean_word_length': 5.096715328467154, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3877655', 'n_tokens_mistral': 2995, 'n_tokens_neox': 2875, 'n_words': 632}