<commit_before>////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2021 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
////////////////////////////////////////////////////////////////////////////////

package com.puppycrawl.tools.checkstyle.meta;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import com.puppycrawl.tools.checkstyle.FileStatefulCheck;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.DetailNode;
import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck;
import com.puppycrawl.tools.checkstyle.utils.TokenUtil;

/**
 * Class for scraping module metadata from the corresponding class' class-level javadoc.
 */
@FileStatefulCheck
public class JavadocMetadataScraper extends AbstractJavadocCheck {

    /** Module details store used for testing. */
    private static final Map<String, ModuleDetails> MODULE_DETAILS_STORE = new HashMap<>();

    /** Regular expression for property location in class-level javadocs. */
    private static final Pattern PROPERTY_TAG = Pattern.compile("\\s*Property\\s*");

    /** Regular expression for property type location in class-level javadocs. */
    private static final Pattern TYPE_TAG = Pattern.compile("^ Type is\\s.*");

    /** Regular expression for property validation type location in class-level javadocs. */
    private static final Pattern VALIDATION_TYPE_TAG =
            Pattern.compile("\\s.*Validation type is\\s.*");

    /** Regular expression for property default value location in class-level javadocs. */
    private static final Pattern DEFAULT_VALUE_TAG = Pattern.compile("^ Default value is:*.*");

    /** Regular expression for check example location in class-level javadocs. */
    private static final Pattern EXAMPLES_TAG =
            Pattern.compile("\\s*To configure the (default )?check.*");

    /** Regular expression for module parent location in class-level javadocs. */
    private static final Pattern PARENT_TAG = Pattern.compile("\\s*Parent is\\s*");

    /** Regular expression for module violation messages location in class-level javadocs. */
    private static final Pattern VIOLATION_MESSAGES_TAG =
            Pattern.compile("\\s*Violation Message Keys:\\s*");

    /** Regular expression for detecting ANTLR tokens(for e.g. CLASS_DEF). */
    private static final Pattern TOKEN_TEXT_PATTERN = Pattern.compile("([A-Z_]{2,})+");

    /** Regular expression for removal of @code{-} present at the beginning of texts. */
    private static final Pattern DESC_CLEAN = Pattern.compile("-\\s");

    /** Regular expression for file separator corresponding to the host OS. */
    private static final Pattern FILE_SEPARATOR_PATTERN =
            Pattern.compile(Pattern.quote(System.getProperty("file.separator")));

    /** Regular expression for quotes. */
    private static final Pattern QUOTE_PATTERN = Pattern.compile("\"");

    /** Java file extension. */
    private static final String JAVA_FILE_EXTENSION = ".java";

    /**
     * This set contains faulty property default value which should not be written to the XML
     * metadata files.
     */
    private static final Set<String> PROPERTIES_TO_NOT_WRITE = Collections.unmodifiableSet(
            new HashSet<>(Arrays.asList(
                    "null",
                    "the charset property of the parent <a href=https://checkstyle.org/"
                        + "config.html#Checker>Checker</a> module"
    )));

    /**
     * Format for exception message for missing type for check property.
     */
    private static final String PROP_TYPE_MISSING = "Type for property '%s' is missing";

    /**
     * Format for exception message for missing default value for check property.
     */
    private static final String PROP_DEFAULT_VALUE_MISSING =
        "Default value for property '%s' is missing";

    /** ModuleDetails instance for each module AST traversal. */
    private ModuleDetails moduleDetails;

    /**
     * Boolean variable which lets us know whether violation message section is being scraped
     * currently.
     */
    private boolean scrapingViolationMessageList;

    /**
     * Boolean variable which lets us know whether we should scan and scrape the current javadoc
     * or not. Since we need only class level javadoc, it becomes true at its root and false after
     * encountering {@code JavadocTokenTypes.SINCE_LITERAL}.
     */
    private boolean toScan;

    /** DetailNode pointing to the root node of the class level javadoc of the class. */
    private DetailNode rootNode;

    /**
     * Child number of the property section node, where parent is the class level javadoc root
     * node.
     */
    private int propertySectionStartIdx;

    /**
     * Child number of the example section node, where parent is the class level javadoc root
     * node.
     */
    private int exampleSectionStartIdx;

    /**
     * Child number of the parent section node, where parent is the class level javadoc root
     * node.
     */
    private int parentSectionStartIdx;

    @Override
    public int[] getDefaultJavadocTokens() {
        return new int[] {
            JavadocTokenTypes.JAVADOC,
            JavadocTokenTypes.PARAGRAPH,
            JavadocTokenTypes.LI,
            JavadocTokenTypes.SINCE_LITERAL,
        };
    }

    @Override
    public int[] getRequiredJavadocTokens() {
        return getAcceptableJavadocTokens();
    }

    @Override
    public void beginJavadocTree(DetailNode rootAst) {
        if (isTopLevelClassJavadoc()) {
            moduleDetails = new ModuleDetails();
            toScan = false;
            scrapingViolationMessageList = false;
            propertySectionStartIdx = -1;
            exampleSectionStartIdx = -1;
            parentSectionStartIdx = -1;

            final String filePath = getFileContents().getFileName();
            String moduleName = getModuleSimpleName();
            final String checkModuleExtension = "Check";
            if (moduleName.contains(checkModuleExtension)) {
                moduleName = moduleName.substring(0, moduleName.indexOf(checkModuleExtension));
            }
            moduleDetails.setName(moduleName);
            moduleDetails.setFullQualifiedName(getPackageName(filePath));
            moduleDetails.setModuleType(getModuleType());
        }
    }

    @Override
    public void visitJavadocToken(DetailNode ast) {<commit_msg>Issue #10756: JavadocMetadataScraper now correctly identifies check name<commit_after>////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2021 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
////////////////////////////////////////////////////////////////////////////////

package com.puppycrawl.tools.checkstyle.meta;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import com.puppycrawl.tools.checkstyle.FileStatefulCheck;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.DetailNode;
import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck;
import com.puppycrawl.tools.checkstyle.utils.TokenUtil;

/**
 * Class for scraping module metadata from the corresponding class' class-level javadoc.
 */
@FileStatefulCheck
public class JavadocMetadataScraper extends AbstractJavadocCheck {

    /** Module details store used for testing. */
    private static final Map<String, ModuleDetails> MODULE_DETAILS_STORE = new HashMap<>();

    /** Regular expression for property location in class-level javadocs. */
    private static final Pattern PROPERTY_TAG = Pattern.compile("\\s*Property\\s*");

    /** Regular expression for property type location in class-level javadocs. */
    private static final Pattern TYPE_TAG = Pattern.compile("^ Type is\\s.*");

    /** Regular expression for property validation type location in class-level javadocs. */
    private static final Pattern VALIDATION_TYPE_TAG =
            Pattern.compile("\\s.*Validation type is\\s.*");

    /** Regular expression for property default value location in class-level javadocs. */
    private static final Pattern DEFAULT_VALUE_TAG = Pattern.compile("^ Default value is:*.*");

    /** Regular expression for check example location in class-level javadocs. */
    private static final Pattern EXAMPLES_TAG =
            Pattern.compile("\\s*To configure the (default )?check.*");

    /** Regular expression for module parent location in class-level javadocs. */
    private static final Pattern PARENT_TAG = Pattern.compile("\\s*Parent is\\s*");

    /** Regular expression for module violation messages location in class-level javadocs. */
    private static final Pattern VIOLATION_MESSAGES_TAG =
            Pattern.compile("\\s*Violation Message Keys:\\s*");

    /** Regular expression for detecting ANTLR tokens(for e.g. CLASS_DEF). */
    private static final Pattern TOKEN_TEXT_PATTERN = Pattern.compile("([A-Z_]{2,})+");

    /** Regular expression for removal of @code{-} present at the beginning of texts. */
    private static final Pattern DESC_CLEAN = Pattern.compile("-\\s");

    /** Regular expression for file separator corresponding to the host OS. */
    private static final Pattern FILE_SEPARATOR_PATTERN =
            Pattern.compile(Pattern.quote(System.getProperty("file.separator")));

    /** Regular expression for quotes. */
    private static final Pattern QUOTE_PATTERN = Pattern.compile("\"");

    /** Java file extension. */
    private static final String JAVA_FILE_EXTENSION = ".java";

    /**
     * This set contains faulty property default value which should not be written to the XML
     * metadata files.
     */
    private static final Set<String> PROPERTIES_TO_NOT_WRITE = Collections.unmodifiableSet(
            new HashSet<>(Arrays.asList(
                    "null",
                    "the charset property of the parent <a href=https://checkstyle.org/"
                        + "config.html#Checker>Checker</a> module"
    )));

    /**
     * Format for exception message for missing type for check property.
     */
    private static final String PROP_TYPE_MISSING = "Type for property '%s' is missing";

    /**
     * Format for exception message for missing default value for check property.
     */
    private static final String PROP_DEFAULT_VALUE_MISSING =
        "Default value for property '%s' is missing";

    /** ModuleDetails instance for each module AST traversal. */
    private ModuleDetails moduleDetails;

    /**
     * Boolean variable which lets us know whether violation message section is being scraped
     * currently.
     */
    private boolean scrapingViolationMessageList;

    /**
     * Boolean variable which lets us know whether we should scan and scrape the current javadoc
     * or not. Since we need only class level javadoc, it becomes true at its root and false after
     * encountering {@code JavadocTokenTypes.SINCE_LITERAL}.
     */
    private boolean toScan;

    /** DetailNode pointing to the root node of the class level javadoc of the class. */
    private DetailNode rootNode;

    /**
     * Child number of the property section node, where parent is the class level javadoc root
     * node.
     */
    private int propertySectionStartIdx;

    /**
     * Child number of the example section node, where parent is the class level javadoc root
     * node.
     */
    private int exampleSectionStartIdx;

    /**
     * Child number of the parent section node, where parent is the class level javadoc root
     * node.
     */
    private int parentSectionStartIdx;

    @Override
    public int[] getDefaultJavadocTokens() {
        return new int[] {
            JavadocTokenTypes.JAVADOC,
            JavadocTokenTypes.PARAGRAPH,
            JavadocTokenTypes.LI,
            JavadocTokenTypes.SINCE_LITERAL,
        };
    }

    @Override
    public int[] getRequiredJavadocTokens() {
        return getAcceptableJavadocTokens();
    }

    @Override
    public void beginJavadocTree(DetailNode rootAst) {
        if (isTopLevelClassJavadoc()) {
            moduleDetails = new ModuleDetails();
            toScan = false;
            scrapingViolationMessageList = false;
            propertySectionStartIdx = -1;
            exampleSectionStartIdx = -1;
            parentSectionStartIdx = -1;

            final String filePath = getFileContents().getFileName();
            String moduleName = getModuleSimpleName();
            final String checkModuleExtension = "Check";
            if (moduleName.endsWith(checkModuleExtension)) {
                moduleName = moduleName
                        .substring(0, moduleName.length() - checkModuleExtension.length());
            }
            moduleDetails.setName(moduleName);
            moduleDetails.setFullQualifiedName(getPackageName(filePath));
            moduleDetails.setModuleType(getModuleType());
        }
    }

    @Override
    public void visitJavadocToken(DetailNode ast) {
{'fraction_non_alphanumeric': 0.10615981183650118, 'fraction_numerical': 0.004004831224969804, 'mean_word_length': 2.847395451210565, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, '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': '1466928', 'n_tokens_mistral': 4194, 'n_tokens_neox': 3952, 'n_words': 1379}